mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2025-12-16 09:12:35 +00:00
Finished removing usage of Excon- package download reimplemented (TODO: see if it's possibly to not need to make n requests to endpoint to emulate excon's chunked downloading), raise Async::Stop when window is closed to shutdown reactor
This commit is contained in:
@@ -11,7 +11,6 @@ class W3DHub
|
|||||||
#! === W3D Hub API === !#
|
#! === W3D Hub API === !#
|
||||||
|
|
||||||
ENDPOINT = "https://secure.w3dhub.com".freeze
|
ENDPOINT = "https://secure.w3dhub.com".freeze
|
||||||
# W3DHUB_API_CONNECTION = Excon.new(ENDPOINT, persistent: true, connect_timeout: 15, tcp_nodelay: true)
|
|
||||||
|
|
||||||
# Method: POST
|
# Method: POST
|
||||||
# FORMAT: JSON
|
# FORMAT: JSON
|
||||||
@@ -151,7 +150,6 @@ class W3DHub
|
|||||||
#! === Server List API === !#
|
#! === Server List API === !#
|
||||||
|
|
||||||
SERVER_LIST_ENDPOINT = "https://gsh.w3dhub.com".freeze
|
SERVER_LIST_ENDPOINT = "https://gsh.w3dhub.com".freeze
|
||||||
# SERVER_LIST_CONNECTION = Excon.new(SERVER_LIST_ENDPOINT, persistent: true, connect_timeout: 15, tcp_nodelay: true)
|
|
||||||
|
|
||||||
# Method: GET
|
# Method: GET
|
||||||
# FORMAT: JSON
|
# FORMAT: JSON
|
||||||
|
|||||||
@@ -473,9 +473,6 @@ class W3DHub
|
|||||||
internet = Async::HTTP::Internet.instance
|
internet = Async::HTTP::Internet.instance
|
||||||
|
|
||||||
Api.package(internet, package) do |chunk, remaining_bytes, total_bytes|
|
Api.package(internet, package) do |chunk, remaining_bytes, total_bytes|
|
||||||
# Store progress somewhere
|
|
||||||
# Kernel.puts "#{name}-#{version}: #{(remaining_bytes.to_f / total_bytes).round}%"
|
|
||||||
|
|
||||||
block&.call(chunk, remaining_bytes, total_bytes)
|
block&.call(chunk, remaining_bytes, total_bytes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
65
lib/cache.rb
65
lib/cache.rb
@@ -46,39 +46,58 @@ class W3DHub
|
|||||||
# Download a W3D Hub package
|
# Download a W3D Hub package
|
||||||
def self.fetch_package(internet, package, block)
|
def self.fetch_package(internet, package, block)
|
||||||
path = package_path(package.category, package.subcategory, package.name, package.version)
|
path = package_path(package.category, package.subcategory, package.name, package.version)
|
||||||
headers = { "Content-Type": "application/x-www-form-urlencoded" }
|
|
||||||
start_from_bytes = package.custom_partially_valid_at_bytes
|
start_from_bytes = package.custom_partially_valid_at_bytes
|
||||||
|
|
||||||
puts " Start from bytes: #{start_from_bytes}"
|
puts " Start from bytes: #{start_from_bytes}"
|
||||||
|
|
||||||
create_directories(path)
|
create_directories(path)
|
||||||
|
|
||||||
file = File.open(path, start_from_bytes.positive? ? "r+b" : "wb")
|
offset = start_from_bytes
|
||||||
if (start_from_bytes.positive?)
|
parts = []
|
||||||
headers["Range"] = "bytes=#{start_from_bytes}-"
|
chunk_size = 4_000_000
|
||||||
file.pos = start_from_bytes
|
workers = 4
|
||||||
|
|
||||||
|
file = File.open(path, offset.positive? ? "r+b" : "wb")
|
||||||
|
|
||||||
|
amount_written = 0
|
||||||
|
|
||||||
|
while (offset < package.size)
|
||||||
|
byte_range_start = offset
|
||||||
|
byte_range_end = [offset + chunk_size, package.size].min
|
||||||
|
parts << (byte_range_start...byte_range_end)
|
||||||
|
|
||||||
|
offset += chunk_size
|
||||||
end
|
end
|
||||||
|
|
||||||
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
semaphore = Async::Semaphore.new(workers)
|
||||||
file.write(chunk)
|
barrier = Async::Barrier.new(parent: semaphore)
|
||||||
|
|
||||||
block.call(chunk, remaining_bytes, total_bytes)
|
while !parts.empty?
|
||||||
puts " Remaining: #{((remaining_bytes.to_f / total_bytes) * 100.0).round}% (#{W3DHub::format_size(total_bytes - remaining_bytes)} / #{W3DHub::format_size(total_bytes)})"
|
barrier.async do
|
||||||
|
part = parts.shift
|
||||||
|
|
||||||
|
range_header = [["range", "bytes=#{part.min}-#{part.max}"]]
|
||||||
|
|
||||||
|
body = "data=#{JSON.dump({ category: package.category, subcategory: package.subcategory, name: package.name, version: package.version })}"
|
||||||
|
response = internet.post("#{Api::ENDPOINT}/apis/launcher/1/get-package", W3DHub::Api::FORM_ENCODED_HEADERS + range_header, body)
|
||||||
|
|
||||||
|
if response.success?
|
||||||
|
chunk = response.read
|
||||||
|
written = file.pwrite(chunk, part.min)
|
||||||
|
|
||||||
|
amount_written += written
|
||||||
|
remaining_bytes = package.size - amount_written
|
||||||
|
total_bytes = package.size
|
||||||
|
|
||||||
|
block.call(chunk, remaining_bytes, total_bytes)
|
||||||
|
# puts " Remaining: #{((remaining_bytes.to_f / total_bytes) * 100.0).round}% (#{W3DHub::format_size(total_bytes - remaining_bytes)} / #{W3DHub::format_size(total_bytes)})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
barrier.wait
|
||||||
end
|
end
|
||||||
|
ensure
|
||||||
# Create a new connection due to some weirdness somewhere in Excon
|
file&.close
|
||||||
response = Excon.post(
|
|
||||||
"#{Api::ENDPOINT}/apis/launcher/1/get-package",
|
|
||||||
tcp_nodelay: true,
|
|
||||||
headers: Api::DEFAULT_HEADERS.merge(headers),
|
|
||||||
body: "data=#{JSON.dump({ category: package.category, subcategory: package.subcategory, name: package.name, version: package.version })}",
|
|
||||||
chunk_size: 4_000_000,
|
|
||||||
response_block: streamer
|
|
||||||
)
|
|
||||||
|
|
||||||
file.close
|
|
||||||
|
|
||||||
response.status == 200 || response.status == 206
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -77,4 +77,6 @@ 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
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user