mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2025-12-15 16:52:34 +00:00
Almost functional websocket based server list updater
This commit is contained in:
@@ -1,62 +1,120 @@
|
||||
class W3DHub
|
||||
class Api
|
||||
class ServerListUpdater
|
||||
class Connection < ::Protocol::WebSocket::Connection
|
||||
##!!! 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
|
||||
if (buffer = super)
|
||||
buffer.split("\x1e").map { |json| parse(json) }
|
||||
end
|
||||
end
|
||||
|
||||
def read1
|
||||
read1&.first
|
||||
end
|
||||
|
||||
def write(object)
|
||||
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
|
||||
|
||||
@@instance = nil
|
||||
|
||||
def self.instance
|
||||
return @@instance if @@instance
|
||||
|
||||
@@instance = ServerListUpdater.new
|
||||
end
|
||||
|
||||
def initialize
|
||||
run
|
||||
end
|
||||
|
||||
# TODO: Properly start up and monitor for updates to server list
|
||||
def initialize
|
||||
def run
|
||||
Async do |task|
|
||||
headers = [["User-Agent", "Cyberarm's Websocket Testing"]]
|
||||
|
||||
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)
|
||||
|
||||
# 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]
|
||||
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.flush
|
||||
# Should be an empty hash for protocol agreement
|
||||
connection.read
|
||||
# Write keep alive?
|
||||
pp connection.read
|
||||
connection.write({ "type": 6 })
|
||||
|
||||
# Subscribe to server changes
|
||||
servers.each_with_index do |server, i|
|
||||
puts "servers: #{Store.server_list&.count}"
|
||||
|
||||
Store.server_list.each_with_index do |server, i|
|
||||
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, 1] }
|
||||
connection.write(out)
|
||||
end
|
||||
|
||||
while (message = connection.read)
|
||||
# Keep alive?
|
||||
connection.write({ type: 6 }) if message.first[:type] == 6
|
||||
|
||||
# TODO: process messages (of type 3?)
|
||||
pp message
|
||||
if message&.first&.fetch(:type) == 1
|
||||
message.each do |rpc|
|
||||
next unless rpc[:target] == "ServerStatusChanged"
|
||||
|
||||
id, data = rpc[:arguments]
|
||||
pp [id, data.length, data]
|
||||
server = Api::ServerListServer.new(data)
|
||||
|
||||
pp [server.player_count, server.max_players]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
ensure
|
||||
@@instance = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -122,6 +122,8 @@ class W3DHub
|
||||
|
||||
Store.server_list_last_fetch = Gosu.milliseconds
|
||||
|
||||
Api::ServerListUpdater.instance
|
||||
|
||||
@tasks[:server_list][:complete] = true
|
||||
rescue => e
|
||||
# Something went wrong!
|
||||
|
||||
Reference in New Issue
Block a user