Compare commits

..

3 Commits

10 changed files with 69 additions and 47 deletions

View File

@@ -12,7 +12,11 @@ gem "websocket-client-simple"
gem "win32-process", platforms: [:x64_mingw, :mingw]
gem "win32-security", platforms: [:x64_mingw, :mingw]
# Packaging on 3.3.0 is... painful. Using 3.2.0 for now.
# bundler 2.5.x doesn't seem to play nice with ocra[n]
# use `bundle _x.y.z_ COMMAND` to use this one...
# group :windows_packaging do
# gem "bundler", "~>2.4.3"
# gem "rake"
# gem "releasy"
# gem "releasy", github: "cyberarm/releasy"
# end

View File

@@ -11,7 +11,7 @@ GEM
rake (>= 12.0.0, < 14.0.0)
event_emitter (0.2.6)
excon (0.109.0)
ffi (1.16.3)
ffi (1.16.3-x64-mingw-ucrt)
ffi-win32-extensions (1.0.4)
ffi
gosu (1.4.6)
@@ -36,8 +36,6 @@ GEM
PLATFORMS
x64-mingw-ucrt
x64-mingw32
x86_64-linux
DEPENDENCIES
base64
@@ -53,4 +51,4 @@ DEPENDENCIES
win32-security
BUNDLED WITH
2.5.3
2.4.3

View File

@@ -11,13 +11,13 @@ Releasy::Project.new do
version W3DHub::VERSION
executable "w3d_hub_linux_launcher.rb"
files ["lib/**/*.*", "locales/*", "media/**/**", "data/.gitkeep", "data/cache/.gitkeep"]
exclude_encoding # Applications that don't use advanced encoding (e.g. Japanese characters) can save build size with this.
files ["lib/**/*.*", "locales/*", "media/**/**", "data/.gitkeep", "data/cache/.gitkeep", "data/logs/.gitkeep"]
# exclude_encoding # Applications that don't use advanced encoding (e.g. Japanese characters) can save build size with this.
verbose
add_build :windows_folder do
icon "media/icons/app.ico"
executable_type :console # Assuming you don't want it to run with a console window.
executable_type :windows # :console # Assuming you don't want it to run with a console window.
add_package :exe # Windows self-extracting archive.
end
end

View File

@@ -22,16 +22,16 @@ class W3DHub
def update(hash)
if @status
@status.instance_variable_set(:@name, hash[:name])
@status.instance_variable_set(:@password, hash[:password] || false)
@status.instance_variable_set(:@map, hash[:map])
@status.instance_variable_set(:@max_players, hash[:maxplayers])
@status.instance_variable_set(:@player_count, hash[:numplayers] || 0)
@status.instance_variable_set(:@started, hash[:started])
@status.instance_variable_set(:@remaining, hash[:remaining])
@status.name = hash[:name]
@status.password = hash[:password] || false
@status.map = hash[:map]
@status.max_players = hash[:maxplayers]
@status.player_count = hash[:numplayers] || 0
@status.started = hash[:started]
@status.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]
@status.teams = hash[:teams]&.map { |t| Team.new(t) } if hash[:teams]
@status.players = hash[:players]&.select { |t| t[:nick] != "Nod" && t[:nick] != "GDI" }&.map { |t| Player.new(t) } if hash[:players]
send_ping
@@ -47,8 +47,6 @@ class W3DHub
W3DHub::BackgroundWorker.foreground_parallel_job(
lambda do
@ping = -1
W3DHub.command("ping #{@address} #{W3DHub.windows? ? '-n 3' : '-c 3'}") do |line|
if W3DHub.windows? && line =~ /Minimum|Maximum|Maximum/i
@ping = line.strip.split(",").last.split("=").last.sub("ms", "").to_i
@@ -57,6 +55,8 @@ class W3DHub
end
end
@ping = -1 if @ping.zero?
@ping
end,
lambda do |_|
@@ -67,7 +67,7 @@ class W3DHub
end
class Status
attr_reader :name, :password, :map, :max_players, :player_count, :started, :remaining, :teams, :players
attr_accessor :name, :password, :map, :max_players, :player_count, :started, :remaining, :teams, :players
def initialize(hash)
@data = hash
@@ -86,7 +86,7 @@ class W3DHub
end
class Team
attr_reader :id, :name, :score, :kills, :deaths
attr_accessor :id, :name, :score, :kills, :deaths
def initialize(hash)
@data = hash
@@ -100,7 +100,7 @@ class W3DHub
end
class Player
attr_reader :nick, :team, :score, :kills, :deaths
attr_accessor :nick, :team, :score, :kills, :deaths
def initialize(hash)
@data = hash

View File

@@ -203,7 +203,12 @@ class W3DHub
def run(app_id, channel, *args)
if (app_data = installed?(app_id, channel))
pid = Process.spawn("#{dxvk_command(app_id, channel)}#{mangohud_command(app_id, channel)}#{wine_command(app_id, channel)}\"#{app_data[:install_path]}\" -launcher #{args.join(' ')}")
install_directory = app_data[:install_directory]
exe_path = app_id == "ecw" ? "#{install_directory}/game500.exe" : "#{install_directory}/game.exe"
exe_path.gsub!("/", "\\") if W3DHub.windows?
exe_path.gsub!("\\", "/") if W3DHub.unix?
pid = Process.spawn("#{dxvk_command(app_id, channel)}#{mangohud_command(app_id, channel)}#{wine_command(app_id, channel)}\"#{exe_path}\" -launcher #{args.join(' ')}")
Process.detach(pid)
end
end
@@ -317,7 +322,7 @@ class W3DHub
if (install_path = reg["InstallDir"])
install_path.gsub!("\\", "/")
exe_path = app_id == "ecw" ? "#{install_path}/game750.exe" : "#{install_path}/game.exe"
exe_path = app_id == "ecw" ? "#{install_path}/game500.exe" : "#{install_path}/game.exe"
if File.exist?(exe_path)
installed_version = app_id == "ren" ? "1.0.0.0" : reg["InstalledVersion"]
@@ -404,6 +409,8 @@ class W3DHub
# wine_prefix # optional
install_directory = Cache.install_path(task.application, task.channel)
install_directory.gsub!("\\", "/")
application_data = {
name: task.application.name,
install_directory: install_directory,

View File

@@ -61,7 +61,7 @@ class W3DHub
status = execute_task
rescue FailFast
# no-op
rescue StandardError, ERRNO::EACCES => e
rescue StandardError, Errno::EACCES => e
status = false
@task_failure_reason = e.message[0..512]
@@ -700,7 +700,7 @@ class W3DHub
File.open("#{path}/#{safe_file_name}", "wb") do |f|
i = entry.get_input_stream
while (chunk = i.read(32_000_000)) # Read up to ~32 MB per chunk
f.write chunk
end

View File

@@ -31,7 +31,9 @@ class W3DHub
# TODO: Show correct application details here
flow(width: 1.0, height: 0.1, padding: 8) do
background task.application.color
app_color = Gosu::Color.new(task.application.color)
app_color.alpha = 0x88
background app_color
flow(width: 0.70, height: 1.0) do
image_path = File.exist?("#{GAME_ROOT_PATH}/media/icons/#{task.app_id}.png") ? "#{GAME_ROOT_PATH}/media/icons/#{task.app_id}.png" : "#{GAME_ROOT_PATH}/media/icons/default_icon.png"
@@ -64,15 +66,15 @@ class W3DHub
task.status.operations.each do |key, operation|
i += 1
stack(width: 1.0, height: 24, padding: 8) do
background 0xff_333333 if i.odd?
stack(width: 1.0, height: 26, padding: 8) do
background 0xaa_333333 if i.odd?
flow(width: 1.0, height: 22) do
@operation_info["#{key}_name"] = para operation.label, width: 0.7, text_wrap: :none, tag: "#{key}_name"
@operation_info["#{key}_status"] = para operation.value, width: 0.3, text_align: :right, text_wrap: :none, tag: "#{key}_status"
end
@operation_info["#{key}_progress"] = progress fraction: operation.progress, height: 2, width: 1.0, tag: "#{key}_progress"
@operation_info["#{key}_progress"] = progress fraction: operation.progress, height: 2, width: 1.0, margin_top: 2, tag: "#{key}_progress"
end
end
end

View File

@@ -205,14 +205,14 @@ class W3DHub
installing = Store.application_manager.task?(:installer, game.id, channel.id)
unless game.id == "ren"
button "<b>#{I18n.t(:"interface.install")}</b>", fill: true, margin_right: 8, text_size: 32, enabled: !installing do |button|
button "<b>#{I18n.t(:"interface.install")}</b>", fill: true, margin_right: 8, text_size: 30, enabled: !installing do |button|
button.enabled = false
@import_button.enabled = false
Store.application_manager.install(game.id, channel.id)
end
end
@import_button = button "<b>#{I18n.t(:"interface.import")}</b>", fill: true, margin_left: 8, text_size: 32, enabled: !installing do
@import_button = button "<b>#{I18n.t(:"interface.import")}</b>", fill: true, margin_left: 8, text_size: 30, enabled: !installing do
Store.application_manager.import(game.id, channel.id)
end
end

View File

@@ -108,7 +108,22 @@ class W3DHub
mask_image = get_image("#{GAME_ROOT_PATH}/media/textures/circle_mask.png")
composite_image = Gosu.render(256, 256) do
avatar_image.draw(0, 0, 0)
scale = 1.0
if avatar_image.width > avatar_image.height
# avatar image is wider than tall, use `height` for scaling to ensure we fill the canvas
scale = 256.0 / avatar_image.height
elsif avatar_image.width < avatar_image.height
# avatar image is taller than wide, use `width` for scaling to ensure we fill the canvas
scale = 256.0 / avatar_image.width
else
# avatar image is square, use width for scale to ensure we fit to the canvas
scale = 256.0 / avatar_image.width
end
# Position image center in middle of composite
avatar_image.draw_rot(128, 128, 0, 0, 0.5, 0.5, scale, scale)
# Render mask image with mode :multiply so we get a clean circle cutout of the scaled avatar image
mask_image.draw(0, 0, 1, 1, 1, 0xff_ffffff, :multiply)
end

View File

@@ -270,10 +270,6 @@ class W3DHub
end
def stylize_selected_server(server_container)
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_active_background = server_container.style.active[:background]
server_container.style.background = @selected_color
server_container.style.default[:background] = @selected_color
@@ -285,10 +281,15 @@ class W3DHub
@server_list_container.children.sort_by! do |child|
s = Store.server_list.find { |s| s.id == child.style.tag }
[s&.status&.player_count, s&.id]
[s.status.player_count, s.id]
end.reverse!.each_with_index do |child, i|
child.style.background = 0xff_333333 if i.even?
child.style.background = 0 if i.odd?
next if @selected_server_container && child == @selected_server_container
child.style.hover[:background] = 0xaa_555566
child.style.hover[:active] = 0xaa_555588
child.style.default[:background] = 0xaa_333333 if i.even?
child.style.default[:background] = 0x00_000000 if i.odd?
end
@server_list_container.recalculate
@@ -341,19 +342,14 @@ class W3DHub
end
server_container.subscribe(:clicked_left_mouse_button) do
if @selected_server_container
@selected_server_container.style.background = @selected_server_container.style.server_item_background
@selected_server_container.style.default[:background] = @selected_server_container.style.server_item_background
@selected_server_container.style.hover[:background] = @selected_server_container.style.server_item_hover_background
@selected_server_container.style.active[:background] = @selected_server_container.style.server_item_active_background
end
stylize_selected_server(server_container)
@selected_server_container = server_container
@selected_server = server
reorder_server_list if @selected_server_container
BackgroundWorker.foreground_job(
-> { fetch_server_details(server) },
->(result) { populate_server_info(server) if server == @selected_server }