WIP API refactor

This commit is contained in:
2026-01-31 14:07:08 -06:00
parent 1425225eef
commit f651143937
2 changed files with 106 additions and 84 deletions

View File

@@ -103,73 +103,91 @@ class W3DHub
# On a failed login the service responds with: # On a failed login the service responds with:
# {"error":"login-failed"} # {"error":"login-failed"}
def self.refresh_user_login(refresh_token, backend = :w3dhub, &callback) def self.refresh_user_login(refresh_token, backend = :w3dhub, &callback)
body = URI.encode_www_form("data": JSON.dump({refreshToken: refresh_token})) handler = lambda do |result|
post("/apis/launcher/1/user-login", FORM_ENCODED_HEADERS, body, backend) do |result|
if result.okay? if result.okay?
user_data = JSON.parse(result.data, symbolize_names: true) user_data = JSON.parse(result.data, symbolize_names: true)
return false if user_data[:error] if user_data[:error]
callback.call(false)
next
end
user_details_data = user_details(user_data[:userid]) || {} user_details_data = user_details(user_data[:userid]) || {}
Account.new(user_data, user_details_data) callback.call(Account.new(user_data, user_details_data))
else else
logger.error(LOG_TAG) { "Failed to fetch refresh user login:" } logger.error(LOG_TAG) { "Failed to fetch refresh user login:" }
logger.error(LOG_TAG) { response } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
body = URI.encode_www_form("data": JSON.dump({ refreshToken: refresh_token }))
post("/apis/launcher/1/user-login", FORM_ENCODED_HEADERS, body, backend, &handler)
end end
# See #user_refresh_token # See #user_refresh_token
def self.user_login(username, password, backend = :w3dhub, &callback) def self.user_login(username, password, backend = :w3dhub, &callback)
body = URI.encode_www_form("data": JSON.dump({username: username, password: password})) handler = lambda do |result|
response = post("/apis/launcher/1/user-login", FORM_ENCODED_HEADERS, body, backend) if result.okay?
user_data = JSON.parse(result.data, symbolize_names: true)
if response.status == 200 if user_data[:error]
user_data = JSON.parse(response.body, symbolize_names: true) callback.call(false)
next
return false if user_data[:error] end
user_details_data = user_details(user_data[:userid]) || {} user_details_data = user_details(user_data[:userid]) || {}
Account.new(user_data, user_details_data) callback.call(Account.new(user_data, user_details_data))
else else
logger.error(LOG_TAG) { "Failed to fetch user login:" } logger.error(LOG_TAG) { "Failed to fetch user login:" }
logger.error(LOG_TAG) { response } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
body = URI.encode_www_form("data": JSON.dump({ username: username, password: password }))
post("/apis/launcher/1/user-login", FORM_ENCODED_HEADERS, body, backend, &handler)
end
# /apis/w3dhub/1/get-user-details # /apis/w3dhub/1/get-user-details
# #
# Response: avatar-uri (Image download uri), id, username # Response: avatar-uri (Image download uri), id, username
def self.user_details(id, backend = :w3dhub, &callback) def self.user_details(id, backend = :w3dhub, &callback)
body = URI.encode_www_form("data": JSON.dump({ id: id })) handler = lambda do |result|
user_details = post("/apis/w3dhub/1/get-user-details", FORM_ENCODED_HEADERS, body, backend) if result.okay?
callback.call(JSON.parse(result.data, symbolize_names: true))
if user_details.status == 200
JSON.parse(user_details.body, symbolize_names: true)
else else
logger.error(LOG_TAG) { "Failed to fetch user details:" } logger.error(LOG_TAG) { "Failed to fetch user details:" }
logger.error(LOG_TAG) { user_details } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
body = URI.encode_www_form("data": JSON.dump({ id: id }))
post("/apis/w3dhub/1/get-user-details", FORM_ENCODED_HEADERS, body, backend, &handler)
end
# /apis/w3dhub/1/get-service-status # /apis/w3dhub/1/get-service-status
# Service response: # Service response:
# {"services":{"authentication":true,"packageDownload":true}} # {"services":{"authentication":true,"packageDownload":true}}
def self.service_status(backend = :w3dhub, &callback) def self.service_status(backend = :w3dhub, &callback)
response = post("/apis/w3dhub/1/get-service-status", DEFAULT_HEADERS, nil, backend) do |result| handler = lambda do |result|
if result.okay? if result.okay?
ServiceStatus.new(result.data) callback.call(ServiceStatus.new(result.data))
else else
logger.error(LOG_TAG) { "Failed to fetch service status:" } logger.error(LOG_TAG) { "Failed to fetch service status:" }
logger.error(LOG_TAG) { response } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
post("/apis/w3dhub/1/get-service-status", DEFAULT_HEADERS, nil, backend, &handler)
end end
# /apis/launcher/1/get-applications # /apis/launcher/1/get-applications
@@ -177,17 +195,20 @@ class W3DHub
# Launcher sends an empty data request: data={} # Launcher sends an empty data request: data={}
# Response is a list of applications/games # Response is a list of applications/games
def self.applications(backend = :w3dhub, &callback) def self.applications(backend = :w3dhub, &callback)
response = post("/apis/launcher/1/get-applications", DEFAULT_HEADERS, nil, backend) handler = lambda do |result|
if result.okay?
if response.status == 200 callback.call(Applications.new(result.data, backend))
Applications.new(response.body, backend)
else else
logger.error(LOG_TAG) { "Failed to fetch applications list:" } logger.error(LOG_TAG) { "Failed to fetch applications list:" }
logger.error(LOG_TAG) { response } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
post("/apis/launcher/1/get-applications", DEFAULT_HEADERS, nil, backend, &handler)
end
# Populate applications list from primary and alternate backends # Populate applications list from primary and alternate backends
# (alternate only has latest public builds of _most_ games) # (alternate only has latest public builds of _most_ games)
def self._applications def self._applications
@@ -262,39 +283,45 @@ class W3DHub
# Client requests news for a specific application/game e.g.: data={"category":"ia"} ("launcher-home" retrieves the weekly hub updates) # Client requests news for a specific application/game e.g.: data={"category":"ia"} ("launcher-home" retrieves the weekly hub updates)
# Response is a JSON hash with a "highlighted" and "news" keys; the "news" one seems to be the desired one # Response is a JSON hash with a "highlighted" and "news" keys; the "news" one seems to be the desired one
def self.news(category, backend = :w3dhub, &callback) def self.news(category, backend = :w3dhub, &callback)
body = URI.encode_www_form("data": JSON.dump({category: category})) handler = lambda do |result|
response = post("/apis/w3dhub/1/get-news", FORM_ENCODED_HEADERS, body, backend) if result.okay?
callback.call(News.new(result.data))
if response.status == 200
News.new(response.body)
else else
logger.error(LOG_TAG) { "Failed to fetch news for:" } logger.error(LOG_TAG) { "Failed to fetch news for:" }
logger.error(LOG_TAG) { category } logger.error(LOG_TAG) { category }
logger.error(LOG_TAG) { response } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
body = URI.encode_www_form("data": JSON.dump({ category: category }))
post("/apis/w3dhub/1/get-news", FORM_ENCODED_HEADERS, body, backend, &handler)
end
# Downloading games # Downloading games
# /apis/launcher/1/get-package-details # /apis/launcher/1/get-package-details
# client requests package details: data={"packages":[{"category":"games","name":"apb.ico","subcategory":"apb","version":""}]} # client requests package details: data={"packages":[{"category":"games","name":"apb.ico","subcategory":"apb","version":""}]}
def self.package_details(packages, backend = :w3dhub, &callback) def self.package_details(packages, backend = :w3dhub, &callback)
body = URI.encode_www_form("data": JSON.dump({ packages: packages })) handler = lambda do |result|
response = post("/apis/launcher/1/get-package-details", FORM_ENCODED_HEADERS, body, backend) if result.okay?
hash = JSON.parse(result.data, symbolize_names: true)
if response.status == 200 callback.call(hash[:packages].map { |pkg| Package.new(pkg) })
hash = JSON.parse(response.body, symbolize_names: true)
hash[:packages].map { |pkg| Package.new(pkg) }
else else
logger.error(LOG_TAG) { "Failed to fetch package details for:" } logger.error(LOG_TAG) { "Failed to fetch package details for:" }
logger.error(LOG_TAG) { packages } logger.error(LOG_TAG) { packages }
logger.error(LOG_TAG) { response } logger.error(LOG_TAG) { result.error }
false
callback.call(false)
end end
end end
body = URI.encode_www_form("data": JSON.dump({ packages: packages }))
post("/apis/launcher/1/get-package-details", FORM_ENCODED_HEADERS, body, backend, &handler)
end
# /apis/launcher/1/get-package # /apis/launcher/1/get-package
# client requests package: data={"category":"games","name":"ECW_Asteroids.zip","subcategory":"ecw","version":"1.0.0.0"} # client requests package: data={"category":"games","name":"ECW_Asteroids.zip","subcategory":"ecw","version":"1.0.0.0"}
# #
@@ -308,17 +335,19 @@ class W3DHub
# #
# clients requests events: data={"serverPath":"apb"} # clients requests events: data={"serverPath":"apb"}
def self.events(app_id, backend = :w3dhub, &callback) def self.events(app_id, backend = :w3dhub, &callback)
body = URI.encode_www_form("data": JSON.dump({ serverPath: app_id })) handler = lambda do |result|
response = post("/apis/w3dhub/1/get-server-events", FORM_ENCODED_HEADERS, body, backend) if result.okay?
if response.status == 200
array = JSON.parse(response.body, symbolize_names: true) array = JSON.parse(response.body, symbolize_names: true)
array.map { |e| Event.new(e) } callback.call(array.map { |e| Event.new(e) })
else else
false callback.call(false)
end end
end end
body = URI.encode_www_form("data": JSON.dump({ serverPath: app_id }))
post("/apis/w3dhub/1/get-server-events", FORM_ENCODED_HEADERS, body, backend, &handler)
end
#! === Server List API === !# #! === Server List API === !#
# SERVER_LIST_ENDPOINT = "https://gsh.w3dhub.com".freeze # SERVER_LIST_ENDPOINT = "https://gsh.w3dhub.com".freeze
@@ -344,23 +373,15 @@ class W3DHub
# nick, team (index of teams array), score, kills, deaths # nick, team (index of teams array), score, kills, deaths
def self.server_list(level = 1, backend = :gsh, &callback) def self.server_list(level = 1, backend = :gsh, &callback)
handler = lambda do |result| handler = lambda do |result|
unless result.okay? if result.okay?
callback.call(false)
next
end
data = JSON.parse(result.data, symbolize_names: true) data = JSON.parse(result.data, symbolize_names: true)
callback.call(data.map { |hash| ServerListServer.new(hash) }) callback.call(data.map { |hash| ServerListServer.new(hash) })
else
callback.call(false)
end
end end
get("/listings/getAll/v2?statusLevel=#{level}", DEFAULT_HEADERS, nil, backend, &handler) get("/listings/getAll/v2?statusLevel=#{level}", DEFAULT_HEADERS, nil, backend, &handler)
# if response.status == 200
# data = JSON.parse(response.body, symbolize_names: true)
# callback&.call(data.map { |hash| ServerListServer.new(hash) })
# end
# callback&.call(false)
end end
# /listings/getStatus/v2/:id?statusLevel=#{0-2} # /listings/getStatus/v2/:id?statusLevel=#{0-2}
@@ -377,14 +398,15 @@ class W3DHub
def self.server_details(id, level, backend = :gsh, &callback) def self.server_details(id, level, backend = :gsh, &callback)
return false unless id && level return false unless id && level
response = get("/listings/getStatus/v2/#{id}?statusLevel=#{level}", DEFAULT_HEADERS, nil, backend) handler = lambda do |result|
if result.okay?
if response.status == 200 callback.call(JSON.parse(response.body, symbolize_names: true))
hash = JSON.parse(response.body, symbolize_names: true) else
return hash callback.call(false)
end
end end
false get("/listings/getStatus/v2/#{id}?statusLevel=#{level}", DEFAULT_HEADERS, nil, backend, &handler)
end end
# /listings/push/v2/negotiate?negotiateVersion=1 # /listings/push/v2/negotiate?negotiateVersion=1

View File

@@ -231,14 +231,14 @@ class W3DHub
def applications def applications
@status_label.value = I18n.t(:"boot.checking_for_updates") @status_label.value = I18n.t(:"boot.checking_for_updates")
Api.on_thread(:_applications) do |applications| # Api.on_thread(:_applications) do |applications|
Api.on_thread(:applications, :alt_w3dhub) do |applications|
if applications if applications
Store.applications = applications Store.applications = applications
Store.settings.save_application_cache(applications.data.to_json) Store.settings.save_application_cache(applications.data.to_json)
@tasks[:applications][:complete] = true @tasks[:applications][:complete] = true
else else
# FIXME: Failed to retreive! @status_label.value = "FAILED TO RETREIVE APPS LIST"
BackgroundWorker.foreground_job(-> {}, ->(_) { @status_label.value = "FAILED TO RETREIVE APPS LIST" })
@offline_mode = true @offline_mode = true
Store.offline_mode = true Store.offline_mode = true