Compare commits

...

3 Commits

5 changed files with 135 additions and 35 deletions

View File

@@ -16,6 +16,18 @@ class W3DHub
@status = @data[:status] ? Status.new(@data[:status]) : nil @status = @data[:status] ? Status.new(@data[:status]) : nil
end end
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])
end
end
class Status class Status
attr_reader :name, :password, :map, :max_players, :player_count, :started, :remaining, :teams, :players attr_reader :name, :password, :map, :max_players, :player_count, :started, :remaining, :teams, :players

View File

@@ -1,60 +1,121 @@
class W3DHub class W3DHub
class Api class Api
class ServerListUpdater class ServerListUpdater
class Connection < ::Protocol::WebSocket::Connection include CyberarmEngine::Common
##!!! When this breaks update from: https://github.com/socketry/async-websocket/blob/master/lib/async/websocket/connection.rb
# refinements preserves super... 😢
class PatchedConnection < ::Protocol::WebSocket::Connection
include ::Protocol::WebSocket::Headers
def self.call(framer, protocol = [], **options)
instance = self.new(framer, Array(protocol).first, **options)
return instance unless block_given?
begin
yield instance
ensure
instance.close
end
end
def initialize(framer, protocol = nil, response: nil, **options)
super(framer, **options)
@protocol = protocol
@response = response
end
def close
super
if @response
@response.finish
@response = nil
end
end
attr :protocol
def read def read
if (buffer = super) if (buffer = super)
buffer.split("\x1e").map { |json| parse(json) } buffer.split("\x1e").map { |json| parse(json) }
end end
end end
def read1
read1&.first
end
def write(object) def write(object)
super(dump(object) + "\x1e") super("#{dump(object)}\x1e")
end
def parse(buffer)
JSON.parse(buffer, symbolize_names: true)
end
def dump(object)
JSON.dump(object)
end
def call
self.close
end end
end end
# TODO: Properly start up and monitor for updates to server list @@instance = nil
def self.instance
return @@instance if @@instance
@@instance = ServerListUpdater.new
end
def initialize def initialize
Async do |task| run
headers = [["User-Agent", "Cyberarm's Websocket Testing"]] end
def run
Async do |task|
internet = Async::HTTP::Internet.instance internet = Async::HTTP::Internet.instance
response = internet.post("https://gsh.w3dhub.com/listings/push/v2/negotiate?negotiateVersion=1", headers, [""]) response = internet.post("https://gsh.w3dhub.com/listings/push/v2/negotiate?negotiateVersion=1", Api::DEFAULT_HEADERS, [""])
data = JSON.parse(response.read, symbolize_names: true) data = JSON.parse(response.read, symbolize_names: true)
# TODO: Replace with Api.server_list
response = internet.get("https://gsh.w3dhub.com/listings/getAll/v2?statusLevel=2", headers, [""])
servers = JSON.parse(response.read, symbolize_names: true)
id = data[:connectionToken] id = data[:connectionToken]
endpoint = Async::HTTP::Endpoint.parse("https://gsh.w3dhub.com/listings/push/v2?id=#{id}", alpn_protocols: Async::HTTP::Protocol::HTTP11.names) endpoint = Async::HTTP::Endpoint.parse("https://gsh.w3dhub.com/listings/push/v2?id=#{id}", alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
Async::WebSocket::Client.connect(endpoint, headers: headers, handler: WSS::Connection) do |connection| Async::WebSocket::Client.connect(endpoint, headers: Api::DEFAULT_HEADERS, handler: PatchedConnection) do |connection|
connection.write({ protocol: "json", version: 1 }) connection.write({ protocol: "json", version: 1 })
connection.flush connection.flush
pp connection.read pp connection.read
connection.write({ "type": 6 }) connection.write({ "type": 6 })
servers.each_with_index do |server, i| Store.server_list.each_with_index do |server, i|
i += 1 i += 1
out = { "type": 1, "invocationId": "#{i}", "target": "SubscribeToServerStatusUpdates", "arguments": [server[:id], 2] } mode = 1 # 2 full details, 1 basic details
out = { "type": 1, "invocationId": "#{i}", "target": "SubscribeToServerStatusUpdates", "arguments": [server.id, mode] }
connection.write(out) connection.write(out)
end end
while (message = connection.read) while (message = connection.read)
connection.write({ type: 6 }) if message.first[:type] == 6 connection.write({ type: 6 }) if message.first[:type] == 6
# TODO: process messages (of type 3?) if message&.first&.fetch(:type) == 1
pp message message.each do |rpc|
next unless rpc[:target] == "ServerStatusChanged"
id, data = rpc[:arguments]
server = Store.server_list.find { |s| s.id == id }
server&.update(data)
state = window.current_state
state.update_server_browser(server) if state.is_a?(States::Interface) && server
end end
end end
end end
end end
ensure
@@instance = nil
end
end
end end
end end
end end

View File

@@ -5,6 +5,7 @@ class W3DHub
@server_locked_icons = {} @server_locked_icons = {}
@selected_server ||= nil @selected_server ||= nil
@selected_server_container ||= nil
@selected_color = 0xff_666655 @selected_color = 0xff_666655
@filters = Store.settings[:server_list_filters] || {} @filters = Store.settings[:server_list_filters] || {}
@@ -119,6 +120,28 @@ class W3DHub
end end
end end
def update
super
populate_server_list if @refresh_server_list
@refresh_server_list = false
end
def refresh_server_list(server)
populate_server_info(server) if @selected_server&.id == server.id
@refresh_server_list = true
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
server_container.style.hover[:background] = @selected_color
server_container.style.active[:background] = @selected_color
end
def populate_server_list def populate_server_list
@server_list_container.scroll_top = 0 @server_list_container.scroll_top = 0
@@ -171,25 +194,23 @@ class W3DHub
end end
server_container.subscribe(:clicked_left_mouse_button) do server_container.subscribe(:clicked_left_mouse_button) do
if @selected_server if @selected_server_container
@selected_server.style.background = @selected_server.style.server_item_background @selected_server_container.style.background = @selected_server_container.style.server_item_background
@selected_server.style.default[:background] = @selected_server.style.server_item_background @selected_server_container.style.default[:background] = @selected_server_container.style.server_item_background
@selected_server.style.hover[:background] = @selected_server.style.server_item_hover_background @selected_server_container.style.hover[:background] = @selected_server_container.style.server_item_hover_background
@selected_server.style.active[:background] = @selected_server.style.server_item_active_background @selected_server_container.style.active[:background] = @selected_server_container.style.server_item_active_background
end end
server_container.style.server_item_background = server_container.style.default[:background] stylize_selected_server(server_container)
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
server_container.style.hover[:background] = @selected_color
server_container.style.active[:background] = @selected_color
@selected_server = server_container @selected_server_container = server_container
@selected_server = server
populate_server_info(server) populate_server_info(server)
end end
stylize_selected_server(server_container) if server.id == @selected_server&.id
end end
end end
end end
@@ -313,7 +334,7 @@ class W3DHub
end end
def fetch_server_list def fetch_server_list
unless Gosu.milliseconds - Store.server_list_last_fetch >= 30_000 # 30 seconds unless Gosu.milliseconds - Store.server_list_last_fetch >= 3_000 # 3 seconds
populate_server_list # Fake it populate_server_list # Fake it
return return
end end

View File

@@ -122,6 +122,8 @@ class W3DHub
Store.server_list_last_fetch = Gosu.milliseconds Store.server_list_last_fetch = Gosu.milliseconds
Api::ServerListUpdater.instance
@tasks[:server_list][:complete] = true @tasks[:server_list][:complete] = true
rescue => e rescue => e
# Something went wrong! # Something went wrong!

View File

@@ -165,8 +165,6 @@ class W3DHub
end end
def page(klass, options = {}) def page(klass, options = {})
# @menu_bar.clear
# @status_bar.clear
body.clear body.clear
@page.blur if @page @page.blur if @page
@@ -179,6 +177,12 @@ class W3DHub
@page.focus @page.focus
end end
def update_server_browser(server)
return unless @page.is_a?(Pages::ServerBrowser)
@page.refresh_server_list(server)
end
def show_application_taskbar def show_application_taskbar
@application_taskbar_container.show @application_taskbar_container.show
end end