diff --git a/lib/application_manager/task.rb b/lib/application_manager/task.rb
index fb0ff69..0b4f608 100644
--- a/lib/application_manager/task.rb
+++ b/lib/application_manager/task.rb
@@ -41,6 +41,10 @@ class W3DHub
@task_state
end
+ def log(string)
+ log string if W3DHUB_DEBUG
+ end
+
# Start task, inside its own thread
# FIXME: Ruby 3 has parallelism now: Use a Ractor to do work on a seperate core to
# prevent the UI from locking up while doing computation heavy work, i.e building
@@ -201,7 +205,7 @@ class W3DHub
packages = []
manifests.reverse.each do |manifest|
- puts "#{manifest.game}-#{manifest.type}: #{manifest.version} (#{manifest.base_version})"
+ log "#{manifest.game}-#{manifest.type}: #{manifest.version} (#{manifest.base_version})"
manifest.files.each do |file|
@files["#{file.name}:#{manifest.version}"] = file
@@ -250,7 +254,11 @@ class W3DHub
file_count = manifests.map { |m| m.files.count }.sum
processed_files = 0
+ folder_exists = File.directory?(path)
+
manifests.each do |manifest|
+ break unless folder_exists
+
manifest.files.each do |file|
safe_file_name = file.name.gsub("\\", "/")
# Fix borked data -> Data 'cause Windows don't care about capitalization
@@ -266,7 +274,7 @@ class W3DHub
unless File.exist?(file_path)
rejected_files << { file: file, manifest_version: manifest.version }
- puts "[#{manifest.version}] File missing: #{file_path}"
+ log "[#{manifest.version}] File missing: #{file_path}"
next
end
@@ -279,21 +287,20 @@ class W3DHub
f.close
- pp file if file.checksum.nil?
+ log file.inspect if file.checksum.nil?
if digest.hexdigest.upcase == file.checksum.upcase
accepted_files[safe_file_name] = manifest.version
- # puts "[#{manifest.version}] Verified file: #{file_path}"
+ log "[#{manifest.version}] Verified file: #{file_path}"
else
rejected_files << { file: file, manifest_version: manifest.version }
- puts "[#{manifest.version}] File failed Verification: #{file_path}"
+ log "[#{manifest.version}] File failed Verification: #{file_path}"
end
end
end
- puts "#{rejected_files.count} missing or corrupt files"
+ log "#{rejected_files.count} missing or corrupt files"
- # TODO: Filter packages to only the required ones
selected_packages = []
selected_packages_hash = {}
@@ -310,10 +317,8 @@ class W3DHub
end
end
- # FIXME: Order `selected_packages` like `packages`
-
# Removed packages that don't need to be fetched or processed
- packages.delete_if { |package| !selected_packages.find { |pkg| pkg == package } }
+ packages.delete_if { |package| !selected_packages.find { |pkg| pkg == package } } if folder_exists
packages
end
@@ -421,7 +426,7 @@ class W3DHub
def unpack_packages(packages)
path = Cache.install_path(@application, @channel)
- puts "Unpacking packages in '#{path}'..."
+ log "Unpacking packages in '#{path}'..."
Cache.create_directories(path, true)
@status.operations.clear
@@ -468,7 +473,7 @@ class W3DHub
update_interface_task_status
else
- puts "COMMAND FAILED!"
+ log "COMMAND FAILED!"
fail!("Failed to unpack #{package.name}")
break
@@ -508,7 +513,7 @@ class W3DHub
@status.step = :mark_application_installed
- puts "#{@app_id} has been installed."
+ log "#{@app_id} has been installed."
end
#############
@@ -540,7 +545,7 @@ class W3DHub
end
def package_fetch(package, &block)
- puts "Downloading: #{package.category}:#{package.subcategory}:#{package.name}-#{package.version}"
+ log "Downloading: #{package.category}:#{package.subcategory}:#{package.name}-#{package.version}"
Api.package(package) do |chunk, remaining_bytes, total_bytes|
block&.call(chunk, remaining_bytes, total_bytes)
@@ -548,7 +553,7 @@ class W3DHub
end
def verify_package(package, &block)
- puts "Verifying: #{package.category}:#{package.subcategory}:#{package.name}-#{package.version}"
+ log "Verifying: #{package.category}:#{package.subcategory}:#{package.name}-#{package.version}"
digest = Digest::SHA256.new
path = Cache.package_path(package.category, package.subcategory, package.name, package.version)
@@ -559,7 +564,7 @@ class W3DHub
operation&.value = "Verifying..."
file_size = File.size(path)
- puts " File size: #{file_size}"
+ log " File size: #{file_size}"
chunk_size = package.checksum_chunk_size
chunks = package.checksum_chunks.size
@@ -584,11 +589,11 @@ class W3DHub
if Digest::SHA256.new.hexdigest(chunk).upcase == checksum.upcase
valid_at = chunk_start + read_length
- # puts " Passed chunk: #{chunk_start}"
+ # log " Passed chunk: #{chunk_start}"
# package.partially_valid_at_bytes = valid_at
package.partially_valid_at_bytes = chunk_start
else
- puts " FAILED chunk: #{chunk_start}"
+ log " FAILED chunk: #{chunk_start}"
break
end
end
@@ -602,25 +607,25 @@ class W3DHub
end
def unpack_package(package, path)
- puts " #{package.name}:#{package.version}"
+ log " #{package.name}:#{package.version}"
package_path = Cache.package_path(package.category, package.subcategory, package.name, package.version)
- puts " Running #{W3DHub.tar_command} command: #{W3DHub.tar_command} -xf \"#{package_path}\" -C \"#{path}\""
+ log " Running #{W3DHub.tar_command} command: #{W3DHub.tar_command} -xf \"#{package_path}\" -C \"#{path}\""
return system("#{W3DHub.tar_command} -xf \"#{package_path}\" -C \"#{path}\"")
end
def apply_patch(package, path)
- puts " #{package.name}:#{package.version}"
+ log " #{package.name}:#{package.version}"
package_path = Cache.package_path(package.category, package.subcategory, package.name, package.version)
temp_path = "#{Store.settings[:package_cache_dir]}/temp"
manifest_file = package.custom_is_patch
Cache.create_directories(temp_path, true)
- puts " Running #{W3DHub.tar_command} command: #{W3DHub.tar_command} -xf \"#{package_path}\" -C \"#{temp_path}\""
+ log " Running #{W3DHub.tar_command} command: #{W3DHub.tar_command} -xf \"#{package_path}\" -C \"#{temp_path}\""
system("#{W3DHub.tar_command} -xf \"#{package_path}\" -C \"#{temp_path}\"")
- puts " Loading #{temp_path}/#{manifest_file.name}.patch..."
+ log " Loading #{temp_path}/#{manifest_file.name}.patch..."
patch_mix = W3DHub::Mixer::Reader.new(file_path: "#{temp_path}/#{manifest_file.name}.patch", ignore_crc_mismatches: false)
patch_info = JSON.parse(patch_mix.package.files.find { |f| f.name == ".w3dhub.patch" || f.name == ".bhppatch" }.data, symbolize_names: true)
@@ -628,15 +633,15 @@ class W3DHub
# Fix borked data -> Data 'cause Windows don't care about capitalization
repaired_path = "#{path}/#{manifest_file.name.sub('data', 'Data')}" unless File.exist?(repaired_path) && path
- puts " Loading #{repaired_path}..."
+ log " Loading #{repaired_path}..."
target_mix = W3DHub::Mixer::Reader.new(file_path: repaired_path, ignore_crc_mismatches: false)
- puts " Removing files..." if patch_info[:removedFiles].size.positive?
+ log " Removing files..." if patch_info[:removedFiles].size.positive?
patch_info[:removedFiles].each do |file|
target_mix.package.files.delete_if { |f| f.name == file }
end
- puts " Adding/Updating files..." if patch_info[:updatedFiles].size.positive?
+ log " Adding/Updating files..." if patch_info[:updatedFiles].size.positive?
patch_info[:updatedFiles].each do |file|
patch = patch_mix.package.files.find { |f| f.name == file }
target = target_mix.package.files.find { |f| f.name == file }
@@ -649,7 +654,7 @@ class W3DHub
end
- puts " Writing updated #{repaired_path}..." if patch_info[:updatedFiles].size.positive?
+ log " Writing updated #{repaired_path}..." if patch_info[:updatedFiles].size.positive?
W3DHub::Mixer::Writer.new(file_path: repaired_path, package: target_mix.package, memory_buffer: true)
FileUtils.remove_dir(temp_path)
@@ -666,7 +671,7 @@ class W3DHub
# Force data/ to Data/
return true unless File.exist?("#{path}/data") && File.directory?("#{path}/data")
- puts " Moving #{path}/data/ to #{path}/Data/"
+ log " Moving #{path}/data/ to #{path}/Data/"
FileUtils.mv(Dir.glob("#{path}/data/**"), "#{path}/Data", force: true)
FileUtils.remove_dir("#{path}/data", force: true)
diff --git a/lib/application_manager/tasks/uninstaller.rb b/lib/application_manager/tasks/uninstaller.rb
index fb72e47..7a38e2e 100644
--- a/lib/application_manager/tasks/uninstaller.rb
+++ b/lib/application_manager/tasks/uninstaller.rb
@@ -33,9 +33,11 @@ class W3DHub
@status.value = "Purging installation folder..."
@status.progress = Float::INFINITY
+ @status.step = :uninstalling_application
+
path = Cache.install_path(@application, @channel)
- puts path
+ log 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)
@@ -51,7 +53,7 @@ class W3DHub
@status.step = :mark_application_uninstalled
- puts "#{@app_id} has been uninstalled."
+ log "#{@app_id} has been uninstalled."
end
end
end
diff --git a/lib/background_worker.rb b/lib/background_worker.rb
index 291f177..8911bb1 100644
--- a/lib/background_worker.rb
+++ b/lib/background_worker.rb
@@ -42,7 +42,11 @@ class W3DHub
while BackgroundWorker.alive?
job = @jobs.shift
- job&.do
+ begin
+ job&.do
+ rescue => e
+ pp e
+ end
sleep 0.1
end
diff --git a/lib/cache.rb b/lib/cache.rb
index 5f83420..ca2c46a 100644
--- a/lib/cache.rb
+++ b/lib/cache.rb
@@ -112,7 +112,7 @@ class W3DHub
tcp_nodelay: true,
headers: headers,
body: "data=#{JSON.dump({ category: package.category, subcategory: package.subcategory, name: package.name, version: package.version })}",
- chunk_size: 4_000_000,
+ chunk_size: 50_000,
response_block: streamer
)
diff --git a/lib/pages/login.rb b/lib/pages/login.rb
index 989ac28..2a6edc0 100644
--- a/lib/pages/login.rb
+++ b/lib/pages/login.rb
@@ -36,29 +36,41 @@ class W3DHub
# Do network stuff
- Api.on_fiber(:user_login, @username.value, @password.value) do |account|
- if account
- Store.account = account
- Store.settings[:account][:data] = account
- Store.settings.save_settings
+ BackgroundWorker.foreground_job(
+ lambda do
+ account = Api.user_login(@username.value, @password.value)
+ applications = nil
- Cache.fetch(account.avatar_uri, true)
+ if account
+ Store.account = account
+ Store.settings[:account][:data] = account
+ Store.settings.save_settings
- populate_account_info
- applications = Api.applications
- Store.applications = applications if applications
+ Cache.fetch(account.avatar_uri, true) if account
+ applications = Api.applications if account
+ end
- page(W3DHub::Pages::Games)
- else
- # An error occurred, enable account entry
- # NOTE: Too many incorrect entries causes lock out (Unknown duration)
- @username.enabled = true
- @password.enabled = true
- btn.enabled = true
+ [account, applications]
+ end,
+ lambda do |result|
+ account, applications = result
- @error_label.value = "Incorrect username or password.\nOr too many failed login attempts, try again in a few minutes."
+ if account
+ populate_account_info
+ Store.applications = applications if applications
+
+ page(W3DHub::Pages::Games)
+ else
+ # An error occurred, enable account entry
+ # NOTE: Too many incorrect entries causes lock out (Unknown duration)
+ @username.enabled = true
+ @password.enabled = true
+ btn.enabled = true
+
+ @error_label.value = "Incorrect username or password.\nOr too many failed login attempts, try again in a few minutes."
+ end
end
- end
+ )
end
@error_label = caption "", width: 1.0, text_align: :center, color: 0xff_800000
@@ -101,22 +113,30 @@ class W3DHub
Store.settings.save_settings
Store.account = nil
- applications = Api.applications
- Store.applications if applications
+ BackgroundWorker.foreground_job(
+ -> { Api.applications },
+ lambda do |applications|
+ if applications
+ Store.applications = applications
+ page(W3DHub::Pages::Games) if @host.current_page.is_a?(W3DHub::Pages::Games)
+ page(W3DHub::Pages::ServerBrowser) if @host.current_page.is_a?(W3DHub::Pages::ServerBrowser)
+ end
- @host.instance_variable_get(:"@account_container").clear do
- stack(width: 0.7, height: 1.0) do
- # background 0xff_222222
- tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none
+ @host.instance_variable_get(:"@account_container").clear do
+ stack(width: 0.7, height: 1.0) do
+ # background 0xff_222222
+ tagline "#{I18n.t(:"interface.not_logged_in")}", text_wrap: :none
- flow(width: 1.0) do
- link(I18n.t(:"interface.log_in"), text_size: 16, width: 0.5) { page(W3DHub::Pages::Login) }
- link I18n.t(:"interface.register"), text_size: 16, width: 0.49 do
- Launchy.open("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register")
+ flow(width: 1.0) do
+ link(I18n.t(:"interface.log_in"), text_size: 16, width: 0.5) { page(W3DHub::Pages::Login) }
+ link I18n.t(:"interface.register"), text_size: 16, width: 0.49 do
+ Launchy.open("https://secure.w3dhub.com/forum/index.php?app=core&module=global§ion=register")
+ end
+ end
end
end
end
- end
+ )
end
end
end
diff --git a/lib/pages/server_browser.rb b/lib/pages/server_browser.rb
index ecb2abb..176d319 100644
--- a/lib/pages/server_browser.rb
+++ b/lib/pages/server_browser.rb
@@ -25,6 +25,7 @@ class W3DHub
flow(width: 0.75, height: 1.0) do
@filters.each do |app_id, enabled|
app = Store.applications.games.find { |a| a.id == app_id.to_s }
+ next unless app
image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{app_id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{app_id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
diff --git a/lib/states/boot.rb b/lib/states/boot.rb
index 9ea0131..7141791 100644
--- a/lib/states/boot.rb
+++ b/lib/states/boot.rb
@@ -34,7 +34,7 @@ class W3DHub
end
def draw
- Gosu.draw_circle(window.width / 2, window.height / 2, @w3dhub_logo.width * Gosu.milliseconds / 1000.0 % 500, 128, 0x44_000000, 32)
+ Gosu.draw_circle(window.width / 2, window.height / 2, @w3dhub_logo.width * (0.6 + Math.cos(Gosu.milliseconds / 1000.0 * Math::PI).abs * 0.05), 128, 0x44_000000, 32)
@w3dhub_logo.draw_rot(window.width / 2, window.height / 2, 32)
super
@@ -43,7 +43,6 @@ class W3DHub
def update
super
- # @fraction += 1.0 * window.dt
@fraction = 1.0 / (@tasks.size / @task_index.to_f)
@progressbar.value = @fraction
@@ -61,8 +60,6 @@ class W3DHub
end
def refresh_user_token
- p :refresh_user_token
-
if Store.settings[:account, :data]
account = Api::Account.new(Store.settings[:account, :data], {})
@@ -99,8 +96,6 @@ class W3DHub
end
def service_status
- p :service_status
-
Api.on_fiber(:service_status) do |service_status|
@service_status = service_status
@@ -119,8 +114,6 @@ class W3DHub
end
def applications
- p :applications
-
@status_label.value = I18n.t(:"boot.checking_for_updates")
Api.on_fiber(:applications) do |applications|
@@ -136,8 +129,6 @@ class W3DHub
end
def app_icons
- puts :app_icons
-
return unless Store.applications
packages = []
@@ -146,8 +137,6 @@ class W3DHub
end
Api.on_fiber(:package_details, packages) do |package_details|
- puts "Got response?"
-
package_details&.each do |package|
path = Cache.package_path(package.category, package.subcategory, package.name, package.version)
generated_icon_path = "#{GAME_ROOT_PATH}/media/icons/#{package.subcategory}.png"
@@ -176,8 +165,6 @@ class W3DHub
end
def server_list
- puts :server_list
-
@status_label.value = I18n.t(:"server_browser.fetching_server_list")
Api.on_fiber(:server_list, 2) do |list|
diff --git a/lib/states/interface.rb b/lib/states/interface.rb
index a6776a3..cdeb27f 100644
--- a/lib/states/interface.rb
+++ b/lib/states/interface.rb
@@ -158,6 +158,10 @@ class W3DHub
@page.focus
end
+ def current_page
+ @page
+ end
+
def update_server_browser(server)
return unless @page.is_a?(Pages::ServerBrowser)
diff --git a/w3d_hub_linux_launcher.rb b/w3d_hub_linux_launcher.rb
index bc0938d..fcfb0ff 100644
--- a/w3d_hub_linux_launcher.rb
+++ b/w3d_hub_linux_launcher.rb
@@ -27,6 +27,8 @@ I18n.load_path << Dir[File.expand_path("locales") + "/*.yml"]
I18n.default_locale = :en
class W3DHub
+ W3DHUB_DEBUG = ARGV.join.include?("--debug")
+
GAME_ROOT_PATH = File.expand_path(".", __dir__)
CACHE_PATH = "#{GAME_ROOT_PATH}/data/cache"
SETTINGS_FILE_PATH = "#{GAME_ROOT_PATH}/data/settings.json"