mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2026-11-04 00:54:09 +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
|
||||
gem "cyberarm_engine"
|
||||
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
|
||||
gem "async"
|
||||
|
||||
65
Gemfile.lock
65
Gemfile.lock
@@ -1,3 +1,8 @@
|
||||
PATH
|
||||
remote: ../gosu
|
||||
specs:
|
||||
gosu (1.5.0)
|
||||
|
||||
GEM
|
||||
remote: https://gem.coop/
|
||||
specs:
|
||||
@@ -27,20 +32,28 @@ GEM
|
||||
fiber-annotation
|
||||
fiber-local (~> 1.1)
|
||||
json
|
||||
cyberarm_engine (0.25.1)
|
||||
cyberarm_engine (0.30.0)
|
||||
gosu (~> 1.1)
|
||||
digest-crc (0.7.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-musl)
|
||||
fiber-annotation (0.2.0)
|
||||
fiber-local (1.1.0)
|
||||
fiber-storage
|
||||
fiber-storage (1.0.1)
|
||||
gosu (1.5.0-x86_64-linux)
|
||||
ffi (~> 1.12)
|
||||
io-endpoint (0.18.0)
|
||||
io-endpoint (0.19.0)
|
||||
openssl (>= 3.3.0)
|
||||
io-event (1.22.0)
|
||||
io-event (1.22.1)
|
||||
io-stream (0.14.0)
|
||||
openssl (>= 3.3)
|
||||
ircparser (1.0.0)
|
||||
@@ -51,7 +64,7 @@ GEM
|
||||
protocol-http (0.72.0)
|
||||
protocol-http1 (0.41.0)
|
||||
protocol-http (~> 0.68)
|
||||
protocol-http2 (0.28.0)
|
||||
protocol-http2 (0.29.1)
|
||||
protocol-hpack (~> 1.4)
|
||||
protocol-http (~> 0.62)
|
||||
protocol-rack (0.23.0)
|
||||
@@ -65,12 +78,22 @@ GEM
|
||||
rack (3.2.7)
|
||||
rake (13.4.2)
|
||||
rexml (3.4.4)
|
||||
rubyzip (3.6.0)
|
||||
rubyzip (3.7.0)
|
||||
sdl3-bindings (1.0.4)
|
||||
ffi (~> 1.16)
|
||||
|
||||
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
|
||||
async
|
||||
@@ -80,7 +103,7 @@ DEPENDENCIES
|
||||
chunky_png
|
||||
cyberarm_engine
|
||||
digest-crc
|
||||
gosu (= 1.5.0)
|
||||
gosu (= 1.5.0)!
|
||||
ircparser
|
||||
json
|
||||
logger
|
||||
@@ -96,15 +119,25 @@ CHECKSUMS
|
||||
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
||||
chunky_png (1.4.0) sha256=89d5b31b55c0cf4da3cf89a2b4ebc3178d8abe8cbaf116a1dba95668502fdcfe
|
||||
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
|
||||
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-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e
|
||||
fiber-annotation (0.2.0) sha256=7abfadf1d119f508867d4103bf231c0354d019cc39a5738945dec2edadaf6c03
|
||||
fiber-local (1.1.0) sha256=c885f94f210fb9b05737de65d511136ea602e00c5105953748aa0f8793489f06
|
||||
fiber-storage (1.0.1) sha256=f48e5b6d8b0be96dac486332b55cee82240057065dc761c1ea692b2e719240e1
|
||||
gosu (1.5.0-x86_64-linux)
|
||||
io-endpoint (0.18.0) sha256=720d186bcd584e8ba490bfc91dab332cc3c5ffee848b5b03894555cb275151aa
|
||||
io-event (1.22.0) sha256=4936d38dfcf2291d897707fd94690f1a63fdb1ea3ab4fa63c6739fc6c61e1534
|
||||
gosu (1.5.0)
|
||||
io-endpoint (0.19.0) sha256=547aaefe9a78bc57fe25f9f7661b460395ebdfda506f70fdf4cc71d2ae5ca578
|
||||
io-event (1.22.1) sha256=0dd054cefe4a29f1b8286604f332c14f3208d75f54902961e91e94d45e5e1600
|
||||
io-stream (0.14.0) sha256=07d9b13ea2066ccbbc761fff8d69ad5a31e47561d31e02cc271f3ed9c1a8f1cd
|
||||
ircparser (1.0.0) sha256=0d4598f691172e2ad078207c50ba62c0d3428ae841836b0a682e6cd01d62878d
|
||||
json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
|
||||
@@ -113,15 +146,15 @@ CHECKSUMS
|
||||
protocol-hpack (1.5.1) sha256=6feca238b8078da1cd295677d6f306c6001af92d75fe0643d33e6956cbc3ad91
|
||||
protocol-http (0.72.0) sha256=b153474785979495b9f2df78f0fdc2e02edc7e92c1f7ea00425eed73bd02194c
|
||||
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-url (0.19.0) sha256=3f6b9f6aa742a259a0b3610fbbd9685dcd9506adf6734f428ff96259faabfb21
|
||||
protocol-websocket (0.21.2) sha256=cbe35be8e045597b221874fba5928d7cd2483884126e3e36faece4741dc88eb7
|
||||
rack (3.2.7) sha256=93e13e1c24f93556671d85d2d79fa228c3485815c50d7e2f265b5330c6528fb7
|
||||
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
||||
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
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.8
|
||||
4.1.0.beta1
|
||||
|
||||
@@ -71,5 +71,9 @@ module W3DHubLauncher
|
||||
|
||||
found_server
|
||||
end
|
||||
|
||||
def self.announce_application_changed(application, state)
|
||||
CyberarmEngine::EventBus.publish("application_changed", { application: application, state: state })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -67,7 +67,7 @@ module W3DHubLauncher
|
||||
|
||||
Worker::Api.update_settings(MemCache[:settings])
|
||||
|
||||
# FIXME: broadcast app installed on CyberarmEngine::EventBus
|
||||
ApplicationHelper.announce_application_changed(app, :installed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -187,7 +187,7 @@ module W3DHubLauncher
|
||||
|
||||
Worker::Api.applications do |result|
|
||||
if result.okay?
|
||||
File.write("applications.json", result.data)
|
||||
File.write("#{CACHE_PATH}/applications.json", result.data)
|
||||
hash = JSON.parse(result.data)
|
||||
applications = hash["applications"]&.map { |app| W3DHubLauncher::Worker::Api::Application.new(app) } || []
|
||||
|
||||
|
||||
@@ -35,11 +35,19 @@ module W3DHubLauncher
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def blur
|
||||
@parent.hide_battleview_panel
|
||||
|
||||
CyberarmEngine::EventBus.unsubscribe("application_changed")
|
||||
end
|
||||
|
||||
def populate_game_content_container
|
||||
@@ -115,7 +123,7 @@ module W3DHubLauncher
|
||||
unless MemCache[:"events_#{app_id}"]
|
||||
Worker::Api.events(app_id) do |result|
|
||||
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) } || []
|
||||
|
||||
populate_game_event if app_id == @current_app.id
|
||||
@@ -126,7 +134,7 @@ module W3DHubLauncher
|
||||
unless MemCache[:"news_#{app_id}"]
|
||||
Worker::Api.news(app_id) do |result|
|
||||
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) } || []
|
||||
|
||||
populate_game_news if app_id == @current_app.id
|
||||
@@ -186,15 +194,25 @@ module W3DHubLauncher
|
||||
|
||||
flow(width: 1.0, height: 60) do
|
||||
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|
|
||||
server = ApplicationHelper.play_now_server(application)
|
||||
if @current_channel.update_available?(application.version)
|
||||
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
|
||||
ApplicationHelper.join_server(application, server)
|
||||
Worker::Api.update_application(@current_app.id, @current_channel.id) do |result, status|
|
||||
handle_task_update(result, status)
|
||||
end
|
||||
end
|
||||
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
|
||||
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)
|
||||
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")
|
||||
stack(width: 1.0, height: 2, background: 0xff_bbbbbb)
|
||||
menu_item("Application Settings", tip: "Edit application launch options")
|
||||
menu_item("Repair Installation", tip: "Attempt to fix and repair installation")
|
||||
menu_item("Check for Updates", tip: "Manually check for application updates")
|
||||
if @current_app.servicable?
|
||||
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)
|
||||
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")
|
||||
if @current_app.servicable?
|
||||
menu_item("Move Installation", tip: "Move application installation to a different directory or disk") do
|
||||
# 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
|
||||
elsif @current_app.servicable?
|
||||
# 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|
|
||||
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_LEFT, **CTA_BUTTON_THEME do |btn|
|
||||
btn.enabled = false
|
||||
|
||||
Worker::Api.install_application(@current_app.id, @current_channel.id) do |status, result|
|
||||
handle_task_update(status, result)
|
||||
Worker::Api.install_application(@current_app.id, @current_channel.id) do |result, status|
|
||||
handle_task_update(result, status)
|
||||
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
|
||||
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)
|
||||
@@ -297,10 +337,12 @@ module W3DHubLauncher
|
||||
when Worker::Request::STATUS_COMPLETE
|
||||
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])
|
||||
|
||||
populate_game_info
|
||||
# FIXME: Application might NOT be installed
|
||||
ApplicationHelper.announce_application_changed(application, :installed)
|
||||
when Worker::Request::STATUS_IN_PROGRESS
|
||||
status_bar.show
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ module W3DHubLauncher
|
||||
end
|
||||
|
||||
# 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
|
||||
flow(width: 1.0, height: 60) do
|
||||
flow(width: 1.0, v_align: :center) do
|
||||
@@ -358,7 +358,7 @@ module W3DHubLauncher
|
||||
def button_up(id)
|
||||
super
|
||||
|
||||
@battleview_container.toggle if id == Gosu::KB_F8
|
||||
# @battleview_container.toggle if id == Gosu::KB_F8
|
||||
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 = {
|
||||
TextBlock: {
|
||||
text_static: true,
|
||||
|
||||
@@ -49,24 +49,38 @@ module W3DHubLauncher
|
||||
@w3dhub_api = W3DHubLauncher::W3DHubApi.new
|
||||
|
||||
Async do |task|
|
||||
UNIXServer.open(IPC_PATH) do |server|
|
||||
while(socket = server.accept)
|
||||
@client = socket
|
||||
task.async do
|
||||
while true
|
||||
@tasks.delete_if { |t| [Request::STATUS_ERROR, Request::STATUS_COMPLETE].include?(t.status) }
|
||||
|
||||
task.async do
|
||||
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"])
|
||||
if @tasks.first && @tasks.all? { |t| t.status == Request::STATUS_PENDING }
|
||||
@tasks.first.start(self)
|
||||
end
|
||||
|
||||
# pp [:server_incoming, data, query]
|
||||
sleep 0.25
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
task.async do |subtask|
|
||||
UNIXServer.open(IPC_PATH) do |server|
|
||||
while(socket = server.accept)
|
||||
@client = socket
|
||||
|
||||
task.async do
|
||||
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
|
||||
@@ -269,8 +283,8 @@ module W3DHubLauncher
|
||||
total_downloaded_bytes: total_downloaded_bytes,
|
||||
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
|
||||
|
||||
@@ -453,15 +467,44 @@ module W3DHubLauncher
|
||||
installed_version: nil,
|
||||
target_version: channel.version
|
||||
)
|
||||
@tasks.last.start(self)
|
||||
|
||||
Response.new(Request::STATUS_PENDING, query.request_id, CyberarmEngine::Result.new(data: true))
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def task_move_application(query)
|
||||
@@ -469,5 +512,20 @@ module W3DHubLauncher
|
||||
|
||||
def task_uninstall_application(query)
|
||||
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
|
||||
|
||||
@@ -100,6 +100,11 @@ module W3DHubLauncher
|
||||
def self.uninstall_application(app_id, channel_id, &block)
|
||||
Worker::Request.new(:task_uninstall_application, { app_id: app_id, channel_id: channel_id }, &block)
|
||||
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
|
||||
|
||||
@@ -80,6 +80,10 @@ module W3DHubLauncher
|
||||
extended_data("serverchannel", @id)
|
||||
end
|
||||
|
||||
def update_available?(current_version)
|
||||
current_version < @version
|
||||
end
|
||||
|
||||
def to_json(context = nil)
|
||||
{
|
||||
"id": @id,
|
||||
|
||||
@@ -41,6 +41,22 @@ module W3DHubLauncher
|
||||
applications.find { |app| app.id == app_id && app.channel == channel_id }
|
||||
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
|
||||
class Preferences
|
||||
SCHEMA = 0
|
||||
|
||||
@@ -6,6 +6,7 @@ module W3DHubLauncher
|
||||
IndexedFile = Data.define(:type, :path)
|
||||
|
||||
attr_reader :request_id, :application, :channel, :installed_version, :target_version
|
||||
attr_reader :status
|
||||
|
||||
def initialize(request_id:, application:, channel:, installed_version:, target_version:)
|
||||
@request_id = request_id
|
||||
@@ -16,6 +17,8 @@ module W3DHubLauncher
|
||||
|
||||
pp self
|
||||
|
||||
@status = Worker::Request::STATUS_PENDING
|
||||
|
||||
# caching mechinism for file path normalization
|
||||
@file_index = {}
|
||||
# manifests!
|
||||
@@ -36,19 +39,28 @@ module W3DHubLauncher
|
||||
end
|
||||
|
||||
def start(worker)
|
||||
return unless status == Worker::Request::STATUS_PENDING
|
||||
|
||||
@worker = worker
|
||||
|
||||
@installation_directory ||= application_target_installation_directory
|
||||
|
||||
update_status(label: "Starting...", fraction: 0.0)
|
||||
|
||||
execute
|
||||
|
||||
@status = Worker::Request::STATUS_BUSY
|
||||
|
||||
v = execute
|
||||
|
||||
@status = Worker::Request::STATUS_COMPLETE
|
||||
v
|
||||
end
|
||||
|
||||
def abort_task!(reason = "")
|
||||
puts reason
|
||||
|
||||
message_requester(Worker::Request::STATUS_ERROR, data: nil, error: reason)
|
||||
@status = Worker::Request::STATUS_ERROR
|
||||
|
||||
raise reason
|
||||
end
|
||||
@@ -120,6 +132,8 @@ module W3DHubLauncher
|
||||
|
||||
@required_manifest_files = @manifest_files.clone
|
||||
|
||||
cached_checksums = {}
|
||||
|
||||
# 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.
|
||||
@manifest_files.reverse.each do |file|
|
||||
@@ -133,13 +147,17 @@ module W3DHubLauncher
|
||||
next unless File.exist?(file_path) # && !File.directory?(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
|
||||
@required_manifest_files.delete(file)
|
||||
|
||||
# remove irrelevant older versions of the file from consideration
|
||||
@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
|
||||
@@ -279,12 +297,14 @@ module W3DHubLauncher
|
||||
timestamp: Time.now.to_i
|
||||
)
|
||||
|
||||
@status = Worker::Request::STATUS_COMPLETE
|
||||
message_requester(Worker::Request::STATUS_COMPLETE, data: { application: app })
|
||||
|
||||
puts "APPLICATION: #{@application.name} #{@application.id}:#{@channel.id}:#{@target_version} installed."
|
||||
end
|
||||
|
||||
def mark_application_uninstalled
|
||||
@status = Worker::Request::STATUS_COMPLETE
|
||||
message_requester(Worker::Request::STATUS_COMPLETE, data: {})
|
||||
end
|
||||
|
||||
@@ -295,7 +315,7 @@ module W3DHubLauncher
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def application_target_installation_directory
|
||||
|
||||
@@ -2,6 +2,7 @@ module W3DHubLauncher
|
||||
class Task
|
||||
class InstallApplication < Task
|
||||
def setup
|
||||
@task_verb = "Installing".freeze
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
# Prevent race condition where server IPC isn't ready before the client attempts to connect
|
||||
sleep 0.1
|
||||
|
||||
# UNIXSocket / client
|
||||
WORKER = W3DHubLauncher::Worker.new
|
||||
WORKER.connect
|
||||
|
||||
Reference in New Issue
Block a user