mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2026-11-05 09:34:13 +00:00
Application updating and repair is now possible, save news and applications listing to cache directory instead of current working directory, added support for application unlinking, misc. other changes
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -9,7 +9,7 @@ gem "json"
|
|||||||
# "game" library gem
|
# "game" library gem
|
||||||
gem "cyberarm_engine"
|
gem "cyberarm_engine"
|
||||||
gem "sdl3-bindings"
|
gem "sdl3-bindings"
|
||||||
gem "gosu", '1.5.0' # temporary, manually built, stand-in for SDL3 supporting gosu
|
gem "gosu", '1.5.0', path: "../gosu" # temporary, manually built, stand-in for SDL3 supporting gosu
|
||||||
|
|
||||||
# networking libs
|
# networking libs
|
||||||
gem "async"
|
gem "async"
|
||||||
|
|||||||
65
Gemfile.lock
65
Gemfile.lock
@@ -1,3 +1,8 @@
|
|||||||
|
PATH
|
||||||
|
remote: ../gosu
|
||||||
|
specs:
|
||||||
|
gosu (1.5.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://gem.coop/
|
remote: https://gem.coop/
|
||||||
specs:
|
specs:
|
||||||
@@ -27,20 +32,28 @@ GEM
|
|||||||
fiber-annotation
|
fiber-annotation
|
||||||
fiber-local (~> 1.1)
|
fiber-local (~> 1.1)
|
||||||
json
|
json
|
||||||
cyberarm_engine (0.25.1)
|
cyberarm_engine (0.30.0)
|
||||||
gosu (~> 1.1)
|
gosu (~> 1.1)
|
||||||
digest-crc (0.7.0)
|
digest-crc (0.7.0)
|
||||||
rake (>= 12.0.0, < 14.0.0)
|
rake (>= 12.0.0, < 14.0.0)
|
||||||
|
ffi (1.17.4)
|
||||||
|
ffi (1.17.4-aarch64-linux-gnu)
|
||||||
|
ffi (1.17.4-aarch64-linux-musl)
|
||||||
|
ffi (1.17.4-arm-linux-gnu)
|
||||||
|
ffi (1.17.4-arm-linux-musl)
|
||||||
|
ffi (1.17.4-arm64-darwin)
|
||||||
|
ffi (1.17.4-x86-linux-gnu)
|
||||||
|
ffi (1.17.4-x86-linux-musl)
|
||||||
|
ffi (1.17.4-x86_64-darwin)
|
||||||
ffi (1.17.4-x86_64-linux-gnu)
|
ffi (1.17.4-x86_64-linux-gnu)
|
||||||
|
ffi (1.17.4-x86_64-linux-musl)
|
||||||
fiber-annotation (0.2.0)
|
fiber-annotation (0.2.0)
|
||||||
fiber-local (1.1.0)
|
fiber-local (1.1.0)
|
||||||
fiber-storage
|
fiber-storage
|
||||||
fiber-storage (1.0.1)
|
fiber-storage (1.0.1)
|
||||||
gosu (1.5.0-x86_64-linux)
|
io-endpoint (0.19.0)
|
||||||
ffi (~> 1.12)
|
|
||||||
io-endpoint (0.18.0)
|
|
||||||
openssl (>= 3.3.0)
|
openssl (>= 3.3.0)
|
||||||
io-event (1.22.0)
|
io-event (1.22.1)
|
||||||
io-stream (0.14.0)
|
io-stream (0.14.0)
|
||||||
openssl (>= 3.3)
|
openssl (>= 3.3)
|
||||||
ircparser (1.0.0)
|
ircparser (1.0.0)
|
||||||
@@ -51,7 +64,7 @@ GEM
|
|||||||
protocol-http (0.72.0)
|
protocol-http (0.72.0)
|
||||||
protocol-http1 (0.41.0)
|
protocol-http1 (0.41.0)
|
||||||
protocol-http (~> 0.68)
|
protocol-http (~> 0.68)
|
||||||
protocol-http2 (0.28.0)
|
protocol-http2 (0.29.1)
|
||||||
protocol-hpack (~> 1.4)
|
protocol-hpack (~> 1.4)
|
||||||
protocol-http (~> 0.62)
|
protocol-http (~> 0.62)
|
||||||
protocol-rack (0.23.0)
|
protocol-rack (0.23.0)
|
||||||
@@ -65,12 +78,22 @@ GEM
|
|||||||
rack (3.2.7)
|
rack (3.2.7)
|
||||||
rake (13.4.2)
|
rake (13.4.2)
|
||||||
rexml (3.4.4)
|
rexml (3.4.4)
|
||||||
rubyzip (3.6.0)
|
rubyzip (3.7.0)
|
||||||
sdl3-bindings (1.0.4)
|
sdl3-bindings (1.0.4)
|
||||||
ffi (~> 1.16)
|
ffi (~> 1.16)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
x86_64-linux
|
aarch64-linux-gnu
|
||||||
|
aarch64-linux-musl
|
||||||
|
arm-linux-gnu
|
||||||
|
arm-linux-musl
|
||||||
|
arm64-darwin
|
||||||
|
ruby
|
||||||
|
x86-linux-gnu
|
||||||
|
x86-linux-musl
|
||||||
|
x86_64-darwin
|
||||||
|
x86_64-linux-gnu
|
||||||
|
x86_64-linux-musl
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
async
|
async
|
||||||
@@ -80,7 +103,7 @@ DEPENDENCIES
|
|||||||
chunky_png
|
chunky_png
|
||||||
cyberarm_engine
|
cyberarm_engine
|
||||||
digest-crc
|
digest-crc
|
||||||
gosu (= 1.5.0)
|
gosu (= 1.5.0)!
|
||||||
ircparser
|
ircparser
|
||||||
json
|
json
|
||||||
logger
|
logger
|
||||||
@@ -96,15 +119,25 @@ CHECKSUMS
|
|||||||
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
||||||
chunky_png (1.4.0) sha256=89d5b31b55c0cf4da3cf89a2b4ebc3178d8abe8cbaf116a1dba95668502fdcfe
|
chunky_png (1.4.0) sha256=89d5b31b55c0cf4da3cf89a2b4ebc3178d8abe8cbaf116a1dba95668502fdcfe
|
||||||
console (1.38.0) sha256=35b82f59130e95e9be6b832d9e539c8b3988fc192e4a8e9a86ab4922f44ad5de
|
console (1.38.0) sha256=35b82f59130e95e9be6b832d9e539c8b3988fc192e4a8e9a86ab4922f44ad5de
|
||||||
cyberarm_engine (0.25.1) sha256=6f851a2ed0a32bdd25fc619172b546a8e26eefeb13a62c509f226337170d0efe
|
cyberarm_engine (0.30.0) sha256=f67d7410c78ad69c865400f9ea23abae74fdf5f9dadae19006cc4fd706064b0f
|
||||||
digest-crc (0.7.0) sha256=64adc23a26a241044cbe6732477ca1b3c281d79e2240bcff275a37a5a0d78c07
|
digest-crc (0.7.0) sha256=64adc23a26a241044cbe6732477ca1b3c281d79e2240bcff275a37a5a0d78c07
|
||||||
|
ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf
|
||||||
|
ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df
|
||||||
|
ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39
|
||||||
|
ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564
|
||||||
|
ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95
|
||||||
|
ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b
|
||||||
|
ffi (1.17.4-x86-linux-gnu) sha256=38e150df5f4ca555e25beca4090823ae09657bceded154e3c52f8631c1ed72cf
|
||||||
|
ffi (1.17.4-x86-linux-musl) sha256=fbeec0fc7c795bcf86f623bb18d31ea1820f7bd580e1703a3d3740d527437809
|
||||||
|
ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496
|
||||||
ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
|
ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
|
||||||
|
ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e
|
||||||
fiber-annotation (0.2.0) sha256=7abfadf1d119f508867d4103bf231c0354d019cc39a5738945dec2edadaf6c03
|
fiber-annotation (0.2.0) sha256=7abfadf1d119f508867d4103bf231c0354d019cc39a5738945dec2edadaf6c03
|
||||||
fiber-local (1.1.0) sha256=c885f94f210fb9b05737de65d511136ea602e00c5105953748aa0f8793489f06
|
fiber-local (1.1.0) sha256=c885f94f210fb9b05737de65d511136ea602e00c5105953748aa0f8793489f06
|
||||||
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)
|
||||||
io-endpoint (0.18.0) sha256=720d186bcd584e8ba490bfc91dab332cc3c5ffee848b5b03894555cb275151aa
|
io-endpoint (0.19.0) sha256=547aaefe9a78bc57fe25f9f7661b460395ebdfda506f70fdf4cc71d2ae5ca578
|
||||||
io-event (1.22.0) sha256=4936d38dfcf2291d897707fd94690f1a63fdb1ea3ab4fa63c6739fc6c61e1534
|
io-event (1.22.1) sha256=0dd054cefe4a29f1b8286604f332c14f3208d75f54902961e91e94d45e5e1600
|
||||||
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.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
|
json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
|
||||||
@@ -113,15 +146,15 @@ CHECKSUMS
|
|||||||
protocol-hpack (1.5.1) sha256=6feca238b8078da1cd295677d6f306c6001af92d75fe0643d33e6956cbc3ad91
|
protocol-hpack (1.5.1) sha256=6feca238b8078da1cd295677d6f306c6001af92d75fe0643d33e6956cbc3ad91
|
||||||
protocol-http (0.72.0) sha256=b153474785979495b9f2df78f0fdc2e02edc7e92c1f7ea00425eed73bd02194c
|
protocol-http (0.72.0) sha256=b153474785979495b9f2df78f0fdc2e02edc7e92c1f7ea00425eed73bd02194c
|
||||||
protocol-http1 (0.41.0) sha256=9863874a1228948a896c3e7ea16d13a680c8f3ed50706007c78b7033018b0ea3
|
protocol-http1 (0.41.0) sha256=9863874a1228948a896c3e7ea16d13a680c8f3ed50706007c78b7033018b0ea3
|
||||||
protocol-http2 (0.28.0) sha256=b7c6195dcfa80ec2484670e9fd8fc21024cc654a391aa0792433aff1188c1691
|
protocol-http2 (0.29.1) sha256=3f4ee667b5730b7d05c70d3771bd5d5cdbb31beedaa9d05f2bdac68c9c984d19
|
||||||
protocol-rack (0.23.0) sha256=63eec3341b20565b3dd155345fd1426ecbbed322cdc8a6accc993905388c03d7
|
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
|
||||||
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
||||||
rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
|
rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
|
||||||
rubyzip (3.6.0) sha256=268994d44d62282d1cfd99bf10eae48d7267199158ad7ea3e1fee2da9458b695
|
rubyzip (3.7.0) sha256=65c19294da75297a939006f3516deacc33185fbd721ff1954f7a231db6d3e121
|
||||||
sdl3-bindings (1.0.4) sha256=326f497c30e6a5cab402e6178403b30c9df4a11a4e109e08c5da6e920c7bb55b
|
sdl3-bindings (1.0.4) sha256=326f497c30e6a5cab402e6178403b30c9df4a11a4e109e08c5da6e920c7bb55b
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
4.0.8
|
4.1.0.beta1
|
||||||
|
|||||||
@@ -71,5 +71,9 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
found_server
|
found_server
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.announce_application_changed(application, state)
|
||||||
|
CyberarmEngine::EventBus.publish("application_changed", { application: application, state: state })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
Worker::Api.update_settings(MemCache[:settings])
|
Worker::Api.update_settings(MemCache[:settings])
|
||||||
|
|
||||||
# FIXME: broadcast app installed on CyberarmEngine::EventBus
|
ApplicationHelper.announce_application_changed(app, :installed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
Worker::Api.applications do |result|
|
Worker::Api.applications do |result|
|
||||||
if result.okay?
|
if result.okay?
|
||||||
File.write("applications.json", result.data)
|
File.write("#{CACHE_PATH}/applications.json", result.data)
|
||||||
hash = JSON.parse(result.data)
|
hash = JSON.parse(result.data)
|
||||||
applications = hash["applications"]&.map { |app| W3DHubLauncher::Worker::Api::Application.new(app) } || []
|
applications = hash["applications"]&.map { |app| W3DHubLauncher::Worker::Api::Application.new(app) } || []
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,19 @@ module W3DHubLauncher
|
|||||||
end
|
end
|
||||||
|
|
||||||
def focus
|
def focus
|
||||||
@parent.show_battleview_panel
|
# @parent.show_battleview_panel
|
||||||
|
|
||||||
|
CyberarmEngine::EventBus.subscribe("application_changed") do |hash|
|
||||||
|
if @current_app&.id == hash[:application].id && @current_channel&.id == hash[:application].channel
|
||||||
|
populate_game_info
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def blur
|
def blur
|
||||||
@parent.hide_battleview_panel
|
@parent.hide_battleview_panel
|
||||||
|
|
||||||
|
CyberarmEngine::EventBus.unsubscribe("application_changed")
|
||||||
end
|
end
|
||||||
|
|
||||||
def populate_game_content_container
|
def populate_game_content_container
|
||||||
@@ -115,7 +123,7 @@ module W3DHubLauncher
|
|||||||
unless MemCache[:"events_#{app_id}"]
|
unless MemCache[:"events_#{app_id}"]
|
||||||
Worker::Api.events(app_id) do |result|
|
Worker::Api.events(app_id) do |result|
|
||||||
if result.okay?
|
if result.okay?
|
||||||
File.write("events_#{app_id}.json", result.data)
|
File.write("#{CACHE_PATH}/events_#{app_id}.json", result.data)
|
||||||
MemCache[:"events_#{app_id}"] = JSON.parse(result.data)&.map { |item| Worker::Api::ServerEvent.new(item) } || []
|
MemCache[:"events_#{app_id}"] = JSON.parse(result.data)&.map { |item| Worker::Api::ServerEvent.new(item) } || []
|
||||||
|
|
||||||
populate_game_event if app_id == @current_app.id
|
populate_game_event if app_id == @current_app.id
|
||||||
@@ -126,7 +134,7 @@ module W3DHubLauncher
|
|||||||
unless MemCache[:"news_#{app_id}"]
|
unless MemCache[:"news_#{app_id}"]
|
||||||
Worker::Api.news(app_id) do |result|
|
Worker::Api.news(app_id) do |result|
|
||||||
if result.okay?
|
if result.okay?
|
||||||
File.write("news_#{app_id}.json", result.data)
|
File.write("#{CACHE_PATH}/news_#{app_id}.json", result.data)
|
||||||
MemCache[:"news_#{app_id}"] = JSON.parse(result.data)["news"]&.map { |item| Worker::Api::NewsItem.new(item) } || []
|
MemCache[:"news_#{app_id}"] = JSON.parse(result.data)["news"]&.map { |item| Worker::Api::NewsItem.new(item) } || []
|
||||||
|
|
||||||
populate_game_news if app_id == @current_app.id
|
populate_game_news if app_id == @current_app.id
|
||||||
@@ -186,15 +194,25 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
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 do |btn|
|
if @current_channel.update_available?(application.version)
|
||||||
server = ApplicationHelper.play_now_server(application)
|
button "Update", tip: "Update application from v#{application.version} to v#{@current_channel.version}", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **UPDATE_BUTTON_THEME do |btn|
|
||||||
|
btn.enabled = false
|
||||||
|
|
||||||
if server
|
Worker::Api.update_application(@current_app.id, @current_channel.id) do |result, status|
|
||||||
ApplicationHelper.join_server(application, server)
|
handle_task_update(result, status)
|
||||||
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
puts "No server available."
|
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
|
||||||
end
|
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
|
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)
|
ApplicationHelper.run(application)
|
||||||
end
|
end
|
||||||
@@ -206,26 +224,48 @@ module W3DHubLauncher
|
|||||||
menu_item("Screenshots Folder", tip: "Open application installation folder:\n#{Dir.home}/Documents/W3D Hub/#{application.id}-#{application.channel}/Screenshots")
|
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: 2, background: 0xff_bbbbbb)
|
stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
|
||||||
menu_item("Application Settings", tip: "Edit application launch options")
|
menu_item("Application Settings", tip: "Edit application launch options")
|
||||||
menu_item("Repair Installation", tip: "Attempt to fix and repair installation")
|
if @current_app.servicable?
|
||||||
menu_item("Check for Updates", tip: "Manually check for application updates")
|
menu_item("Repair Installation", tip: "Attempt to fix and repair installation") do
|
||||||
|
Worker::Api.repair_application(@current_app.id, @current_channel.id) do |result, status|
|
||||||
|
handle_task_update(result, status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
menu_item("Check for Updates", tip: "Manually check for application updates")
|
||||||
|
end
|
||||||
stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
|
stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
|
||||||
menu_item("Move Installation", tip: "Move application installation to a different directory or disk")
|
if @current_app.servicable?
|
||||||
menu_item("Unlink Installation", tip: "The application will be removed from the launcher\nbut the application's files will not be touched")
|
menu_item("Move Installation", tip: "Move application installation to a different directory or disk") do
|
||||||
menu_item("Uninstall", tip: "Uninstall application and delete files")
|
# FIXME: Show a prompt dialog for choosing new location
|
||||||
|
# Worker::Api.move_application(@current_app.id, @current_channel.id) do |result, status|
|
||||||
|
# handle_task_update(result, status)
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
menu_item("Unlink Installation", tip: "The application will be removed from the launcher\nbut the application's files will not be touched") do
|
||||||
|
Worker::Api.unlink_application(@current_app.id, @current_channel.id) do |result, status|
|
||||||
|
if result.okay?
|
||||||
|
MemCache[:settings] = Worker::Api::Settings.new(JSON.parse(result.data))
|
||||||
|
populate_game_info
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @current_app.servicable?
|
||||||
|
menu_item("Uninstall", tip: "Uninstall application and delete files")
|
||||||
|
end
|
||||||
end.show
|
end.show
|
||||||
end
|
end
|
||||||
elsif @current_app.servicable?
|
elsif @current_app.servicable?
|
||||||
# pp @current_app
|
# pp @current_app
|
||||||
button "Import", tip: "Import existing application installation", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **CTA_BUTTON_THEME do |btn|
|
button "Download", tip: "Download and install application", 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|
|
|
||||||
btn.enabled = false
|
btn.enabled = false
|
||||||
|
|
||||||
Worker::Api.install_application(@current_app.id, @current_channel.id) do |status, result|
|
Worker::Api.install_application(@current_app.id, @current_channel.id) do |result, status|
|
||||||
handle_task_update(status, result)
|
handle_task_update(result, status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
button "Import", tip: "Import existing application installation", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_RIGHT, **CTA_BUTTON_THEME do |btn|
|
||||||
|
dialog(Dialog::ImportApplication, application: @current_app, channel: @current_channel)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
button "Import", tip: "Import existing application installation", fill: true, height: 1.0, **CTA_BUTTON_THEME do |btn|
|
button "Import", tip: "Import existing application installation", fill: true, height: 1.0, **CTA_BUTTON_THEME do |btn|
|
||||||
dialog(Dialog::ImportApplication, application: @current_app, channel: @current_channel)
|
dialog(Dialog::ImportApplication, application: @current_app, channel: @current_channel)
|
||||||
@@ -297,10 +337,12 @@ module W3DHubLauncher
|
|||||||
when Worker::Request::STATUS_COMPLETE
|
when Worker::Request::STATUS_COMPLETE
|
||||||
status_bar.hide
|
status_bar.hide
|
||||||
|
|
||||||
MemCache[:settings].applications << Worker::Api::Settings::Application.new(data["application"])
|
# FIXME: Application might NOT be installed
|
||||||
|
application = MemCache[:settings].add_or_update_application(Worker::Api::Settings::Application.new(data["application"]))
|
||||||
Worker::Api.update_settings(MemCache[:settings])
|
Worker::Api.update_settings(MemCache[:settings])
|
||||||
|
|
||||||
populate_game_info
|
# FIXME: Application might NOT be installed
|
||||||
|
ApplicationHelper.announce_application_changed(application, :installed)
|
||||||
when Worker::Request::STATUS_IN_PROGRESS
|
when Worker::Request::STATUS_IN_PROGRESS
|
||||||
status_bar.show
|
status_bar.show
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ module W3DHubLauncher
|
|||||||
end
|
end
|
||||||
|
|
||||||
# battleview/friends container
|
# battleview/friends container
|
||||||
@battleview_container = stack(width: 400, height: 1.0, margin_left: LARGE_PADDING) do
|
@battleview_container = stack(width: 400, height: 1.0, margin_left: LARGE_PADDING, visible: false) do
|
||||||
# friend management container
|
# friend management container
|
||||||
flow(width: 1.0, height: 60) do
|
flow(width: 1.0, height: 60) do
|
||||||
flow(width: 1.0, v_align: :center) do
|
flow(width: 1.0, v_align: :center) do
|
||||||
@@ -358,7 +358,7 @@ module W3DHubLauncher
|
|||||||
def button_up(id)
|
def button_up(id)
|
||||||
super
|
super
|
||||||
|
|
||||||
@battleview_container.toggle if id == Gosu::KB_F8
|
# @battleview_container.toggle if id == Gosu::KB_F8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
13
lib/theme.rb
13
lib/theme.rb
@@ -39,6 +39,19 @@ module W3DHubLauncher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UPDATE_BUTTON_THEME = {
|
||||||
|
color: 0xff_ffffff,
|
||||||
|
background_nine_slice_color: 0xff_e66100,
|
||||||
|
hover: {
|
||||||
|
color: 0xff_ffffff,
|
||||||
|
background_nine_slice_color: 0xff_ff7800
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
color: 0xff_ffffff,
|
||||||
|
background_nine_slice_color: 0xff_c64600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
THEME = {
|
THEME = {
|
||||||
TextBlock: {
|
TextBlock: {
|
||||||
text_static: true,
|
text_static: true,
|
||||||
|
|||||||
@@ -49,24 +49,38 @@ module W3DHubLauncher
|
|||||||
@w3dhub_api = W3DHubLauncher::W3DHubApi.new
|
@w3dhub_api = W3DHubLauncher::W3DHubApi.new
|
||||||
|
|
||||||
Async do |task|
|
Async do |task|
|
||||||
UNIXServer.open(IPC_PATH) do |server|
|
task.async do
|
||||||
while(socket = server.accept)
|
while true
|
||||||
@client = socket
|
@tasks.delete_if { |t| [Request::STATUS_ERROR, Request::STATUS_COMPLETE].include?(t.status) }
|
||||||
|
|
||||||
task.async do
|
if @tasks.first && @tasks.all? { |t| t.status == Request::STATUS_PENDING }
|
||||||
while(data = socket.gets)
|
@tasks.first.start(self)
|
||||||
json = JSON.parse(data)
|
end
|
||||||
query = Request::Query.new(type: json["type"].to_sym, request_id: json["request_id"], data: json["data"])
|
|
||||||
|
|
||||||
# pp [:server_incoming, data, query]
|
sleep 0.25
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if respond_to?(query.type)
|
task.async do |subtask|
|
||||||
response = send(query.type, query)
|
UNIXServer.open(IPC_PATH) do |server|
|
||||||
# pp [:server_to_client, response]
|
while(socket = server.accept)
|
||||||
payload = { status: response.status, request_id: response.request_id, data: response.result.data, error: response.result.error }.to_json
|
@client = socket
|
||||||
socket.write(payload)
|
|
||||||
socket.write(RESPONSE_SEPARATOR)
|
task.async do
|
||||||
socket.flush
|
while(data = socket.gets)
|
||||||
|
json = JSON.parse(data)
|
||||||
|
query = Request::Query.new(type: json["type"].to_sym, request_id: json["request_id"], data: json["data"])
|
||||||
|
|
||||||
|
# pp [:server_incoming, data, query]
|
||||||
|
|
||||||
|
if respond_to?(query.type)
|
||||||
|
response = send(query.type, query)
|
||||||
|
# pp [:server_to_client, response]
|
||||||
|
payload = { status: response.status, request_id: response.request_id, data: response.result.data, error: response.result.error }.to_json
|
||||||
|
socket.write(payload)
|
||||||
|
socket.write(RESPONSE_SEPARATOR)
|
||||||
|
socket.flush
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -269,8 +283,8 @@ module W3DHubLauncher
|
|||||||
total_downloaded_bytes: total_downloaded_bytes,
|
total_downloaded_bytes: total_downloaded_bytes,
|
||||||
content_length: content_length
|
content_length: content_length
|
||||||
})
|
})
|
||||||
# FIXME: Send intermediate response to requester
|
|
||||||
# send(query, Response.new(Request::STATUS_IN_PROGRESS, query.request_id progress_result))
|
message_requester(query.request_id, Request::STATUS_IN_PROGRESS, progress_result.data, progress_result.error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -453,15 +467,44 @@ module W3DHubLauncher
|
|||||||
installed_version: nil,
|
installed_version: nil,
|
||||||
target_version: channel.version
|
target_version: channel.version
|
||||||
)
|
)
|
||||||
@tasks.last.start(self)
|
|
||||||
|
|
||||||
Response.new(Request::STATUS_PENDING, query.request_id, CyberarmEngine::Result.new(data: true))
|
Response.new(Request::STATUS_PENDING, query.request_id, CyberarmEngine::Result.new(data: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
def task_update_application(query)
|
def task_update_application(query)
|
||||||
|
application = @w3dhub_api.applications.find { |app| app.id == query.data["app_id"] }
|
||||||
|
channel = application.channels.find { |chan| chan.id == query.data["channel_id"] }
|
||||||
|
|
||||||
|
settings_application = @settings.application_installed?(application.id, channel.id)
|
||||||
|
|
||||||
|
@tasks << Task::UpdateApplication.new(
|
||||||
|
request_id: query.request_id,
|
||||||
|
application: application,
|
||||||
|
channel: channel,
|
||||||
|
installed_version: settings_application.version,
|
||||||
|
target_version: channel.version
|
||||||
|
)
|
||||||
|
|
||||||
|
Response.new(Request::STATUS_PENDING, query.request_id, CyberarmEngine::Result.new(data: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
def task_repair_application(query)
|
def task_repair_application(query)
|
||||||
|
application = @w3dhub_api.applications.find { |app| app.id == query.data["app_id"] }
|
||||||
|
channel = application.channels.find { |chan| chan.id == query.data["channel_id"] }
|
||||||
|
|
||||||
|
settings_application = @settings.application_installed?(application.id, channel.id)
|
||||||
|
|
||||||
|
@tasks << Task::RepairApplication.new(
|
||||||
|
request_id: query.request_id,
|
||||||
|
application: application,
|
||||||
|
channel: channel,
|
||||||
|
installed_version: settings_application.version,
|
||||||
|
target_version: settings_application.version
|
||||||
|
)
|
||||||
|
|
||||||
|
pp @tasks.last
|
||||||
|
|
||||||
|
Response.new(Request::STATUS_PENDING, query.request_id, CyberarmEngine::Result.new(data: true))
|
||||||
end
|
end
|
||||||
|
|
||||||
def task_move_application(query)
|
def task_move_application(query)
|
||||||
@@ -469,5 +512,20 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
def task_uninstall_application(query)
|
def task_uninstall_application(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def unlink_application(query)
|
||||||
|
result = CyberarmEngine::Result.new
|
||||||
|
|
||||||
|
application = @settings.application_installed?(query.data["app_id"], query.data["channel_id"])
|
||||||
|
|
||||||
|
if application
|
||||||
|
@settings.remove_application(application)
|
||||||
|
|
||||||
|
query = Request::Query.new(query.type, query.request_id, @settings.to_json)
|
||||||
|
return update_settings(query)
|
||||||
|
end
|
||||||
|
|
||||||
|
deliver_response(result, query)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ module W3DHubLauncher
|
|||||||
def self.uninstall_application(app_id, channel_id, &block)
|
def self.uninstall_application(app_id, channel_id, &block)
|
||||||
Worker::Request.new(:task_uninstall_application, { app_id: app_id, channel_id: channel_id }, &block)
|
Worker::Request.new(:task_uninstall_application, { app_id: app_id, channel_id: channel_id }, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# request unlinking of application
|
||||||
|
def self.unlink_application(app_id, channel_id, &block)
|
||||||
|
Worker::Request.new(:unlink_application, { app_id: app_id, channel_id: channel_id }, &block)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ module W3DHubLauncher
|
|||||||
extended_data("serverchannel", @id)
|
extended_data("serverchannel", @id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_available?(current_version)
|
||||||
|
current_version < @version
|
||||||
|
end
|
||||||
|
|
||||||
def to_json(context = nil)
|
def to_json(context = nil)
|
||||||
{
|
{
|
||||||
"id": @id,
|
"id": @id,
|
||||||
|
|||||||
@@ -41,6 +41,22 @@ module W3DHubLauncher
|
|||||||
applications.find { |app| app.id == app_id && app.channel == channel_id }
|
applications.find { |app| app.id == app_id && app.channel == channel_id }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_or_update_application(application)
|
||||||
|
index = applications.index { |app| app.id == application.id && app.channel == application.channel }
|
||||||
|
|
||||||
|
if index
|
||||||
|
applications[index] = application
|
||||||
|
else
|
||||||
|
applications << application
|
||||||
|
end
|
||||||
|
|
||||||
|
application
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_application(application)
|
||||||
|
applications.delete(application)
|
||||||
|
end
|
||||||
|
|
||||||
# User explictly set options
|
# User explictly set options
|
||||||
class Preferences
|
class Preferences
|
||||||
SCHEMA = 0
|
SCHEMA = 0
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ module W3DHubLauncher
|
|||||||
IndexedFile = Data.define(:type, :path)
|
IndexedFile = Data.define(:type, :path)
|
||||||
|
|
||||||
attr_reader :request_id, :application, :channel, :installed_version, :target_version
|
attr_reader :request_id, :application, :channel, :installed_version, :target_version
|
||||||
|
attr_reader :status
|
||||||
|
|
||||||
def initialize(request_id:, application:, channel:, installed_version:, target_version:)
|
def initialize(request_id:, application:, channel:, installed_version:, target_version:)
|
||||||
@request_id = request_id
|
@request_id = request_id
|
||||||
@@ -16,6 +17,8 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
pp self
|
pp self
|
||||||
|
|
||||||
|
@status = Worker::Request::STATUS_PENDING
|
||||||
|
|
||||||
# caching mechinism for file path normalization
|
# caching mechinism for file path normalization
|
||||||
@file_index = {}
|
@file_index = {}
|
||||||
# manifests!
|
# manifests!
|
||||||
@@ -36,19 +39,28 @@ module W3DHubLauncher
|
|||||||
end
|
end
|
||||||
|
|
||||||
def start(worker)
|
def start(worker)
|
||||||
|
return unless status == Worker::Request::STATUS_PENDING
|
||||||
|
|
||||||
@worker = worker
|
@worker = worker
|
||||||
|
|
||||||
@installation_directory ||= application_target_installation_directory
|
@installation_directory ||= application_target_installation_directory
|
||||||
|
|
||||||
update_status(label: "Starting...", fraction: 0.0)
|
update_status(label: "Starting...", fraction: 0.0)
|
||||||
|
|
||||||
execute
|
|
||||||
|
@status = Worker::Request::STATUS_BUSY
|
||||||
|
|
||||||
|
v = execute
|
||||||
|
|
||||||
|
@status = Worker::Request::STATUS_COMPLETE
|
||||||
|
v
|
||||||
end
|
end
|
||||||
|
|
||||||
def abort_task!(reason = "")
|
def abort_task!(reason = "")
|
||||||
puts reason
|
puts reason
|
||||||
|
|
||||||
message_requester(Worker::Request::STATUS_ERROR, data: nil, error: reason)
|
message_requester(Worker::Request::STATUS_ERROR, data: nil, error: reason)
|
||||||
|
@status = Worker::Request::STATUS_ERROR
|
||||||
|
|
||||||
raise reason
|
raise reason
|
||||||
end
|
end
|
||||||
@@ -120,6 +132,8 @@ module W3DHubLauncher
|
|||||||
|
|
||||||
@required_manifest_files = @manifest_files.clone
|
@required_manifest_files = @manifest_files.clone
|
||||||
|
|
||||||
|
cached_checksums = {}
|
||||||
|
|
||||||
# Process manifest game files in NEWEST to OLDEST order so that we don't erroneously flag
|
# Process manifest game files in NEWEST to OLDEST order so that we don't erroneously flag
|
||||||
# valid files as invalid due to an OLDER version of the file being checked FIRST.
|
# valid files as invalid due to an OLDER version of the file being checked FIRST.
|
||||||
@manifest_files.reverse.each do |file|
|
@manifest_files.reverse.each do |file|
|
||||||
@@ -133,13 +147,17 @@ module W3DHubLauncher
|
|||||||
next unless File.exist?(file_path) # && !File.directory?(file_path)
|
next unless File.exist?(file_path) # && !File.directory?(file_path)
|
||||||
|
|
||||||
puts "verifying #{file_path}..."
|
puts "verifying #{file_path}..."
|
||||||
checksum = Digest::SHA256.file(file_path).hexdigest.upcase
|
checksum = cached_checksums[file_path] || Digest::SHA256.file(file_path).hexdigest.upcase
|
||||||
|
cached_checksums[file_path] ||= checksum
|
||||||
|
|
||||||
if checksum == file.checksum
|
if checksum == file.checksum
|
||||||
@required_manifest_files.delete(file)
|
@required_manifest_files.delete(file)
|
||||||
|
|
||||||
# remove irrelevant older versions of the file from consideration
|
# remove irrelevant older versions of the file from consideration
|
||||||
@required_manifest_files.delete_if { |f| f.name.casecmp?(file.name) && f.version < file.version }
|
@required_manifest_files.delete_if { |f| f.name.casecmp?(file.name) && f.version < file.version }
|
||||||
|
puts " verified:#{file.version}"
|
||||||
|
else
|
||||||
|
puts " failed verification:#{file.version}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -279,12 +297,14 @@ module W3DHubLauncher
|
|||||||
timestamp: Time.now.to_i
|
timestamp: Time.now.to_i
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@status = Worker::Request::STATUS_COMPLETE
|
||||||
message_requester(Worker::Request::STATUS_COMPLETE, data: { application: app })
|
message_requester(Worker::Request::STATUS_COMPLETE, data: { application: app })
|
||||||
|
|
||||||
puts "APPLICATION: #{@application.name} #{@application.id}:#{@channel.id}:#{@target_version} installed."
|
puts "APPLICATION: #{@application.name} #{@application.id}:#{@channel.id}:#{@target_version} installed."
|
||||||
end
|
end
|
||||||
|
|
||||||
def mark_application_uninstalled
|
def mark_application_uninstalled
|
||||||
|
@status = Worker::Request::STATUS_COMPLETE
|
||||||
message_requester(Worker::Request::STATUS_COMPLETE, data: {})
|
message_requester(Worker::Request::STATUS_COMPLETE, data: {})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -295,7 +315,7 @@ module W3DHubLauncher
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_status(label:, fraction:)
|
def update_status(label:, fraction:)
|
||||||
message_requester(data: { status: { title: "TASK #{@application.name} (#{@channel.name})", label: label, fraction: fraction } } )
|
message_requester(data: { status: { title: "#{@task_verb} #{@application.name} (#{@channel.name})", label: label, fraction: fraction } } )
|
||||||
end
|
end
|
||||||
|
|
||||||
def application_target_installation_directory
|
def application_target_installation_directory
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ module W3DHubLauncher
|
|||||||
class Task
|
class Task
|
||||||
class InstallApplication < Task
|
class InstallApplication < Task
|
||||||
def setup
|
def setup
|
||||||
|
@task_verb = "Installing".freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module W3DHubLauncher
|
||||||
|
class Task
|
||||||
|
class RepairApplication < InstallApplication
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
|
||||||
|
@task_verb = "Repairing".freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module W3DHubLauncher
|
||||||
|
class Task
|
||||||
|
class UpdateApplication < InstallApplication
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
|
||||||
|
@task_verb = "Updating".freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ module W3DHubLauncher
|
|||||||
W3DHubLauncher::Worker.new.listen
|
W3DHubLauncher::Worker.new.listen
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Prevent race condition where server IPC isn't ready before the client attempts to connect
|
||||||
|
sleep 0.1
|
||||||
|
|
||||||
# UNIXSocket / client
|
# UNIXSocket / client
|
||||||
WORKER = W3DHubLauncher::Worker.new
|
WORKER = W3DHubLauncher::Worker.new
|
||||||
WORKER.connect
|
WORKER.connect
|
||||||
|
|||||||
Reference in New Issue
Block a user