TACNET is now able to dynamically sync configs on initial connection, added error sound, made tacnet status dialog update stats, made simulator clock stop after all robots have run out of 'states' to run, changed some dialogs titlebar and borders to be different colors, misc. other changes.

This commit is contained in:
2020-09-08 19:25:04 -05:00
parent 08ada79e5b
commit 9dc3caca0f
17 changed files with 257 additions and 41 deletions

View File

@@ -2,7 +2,7 @@ module TAC
class TACNET
class Packet
PROTOCOL_VERSION = 1
PROTOCOL_HEADER_SEPERATOR = "|"
PROTOCOL_SEPERATOR = "|"
PROTOCOL_HEARTBEAT = "heartbeat"
PACKET_TYPES = {
@@ -12,6 +12,11 @@ module TAC
download_config: 10,
upload_config: 11,
list_configs: 12,
select_config: 13,
add_config: 14,
update_config: 15,
delete_config: 16,
add_group: 20,
update_group: 21,
@@ -30,7 +35,7 @@ module TAC
slice = message.split("|", 4)
if slice.size < 4
warn "Failed to split packet along first 4 " + PROTOCOL_HEADER_SEPERATOR + ". Raw return: " + slice.to_s
warn "Failed to split packet along first 4 " + PROTOCOL_SEPERATOR + ". Raw return: " + slice.to_s
return nil
end
@@ -73,11 +78,11 @@ module TAC
def encode_header
string = ""
string += protocol_version.to_s
string += PROTOCOL_HEADER_SEPERATOR
string += PROTOCOL_SEPERATOR
string += PACKET_TYPES[type].to_s
string += PROTOCOL_HEADER_SEPERATOR
string += PROTOCOL_SEPERATOR
string += content_length.to_s
string += PROTOCOL_HEADER_SEPERATOR
string += PROTOCOL_SEPERATOR
return string
end

View File

@@ -10,6 +10,7 @@ module TAC
packet = Packet.from_stream(message)
if packet
log.i(TAG, "Received packet of type: #{packet.type}")
hand_off(packet)
else
log.d(TAG, "Rejected raw packet: #{message}")
@@ -24,10 +25,21 @@ module TAC
handle_heartbeat(packet)
when :error
handle_error(packet)
when :download_config
handle_download_config(packet)
when :upload_config
handle_upload_config(packet)
when :list_configs
handle_list_configs(packet)
when :select_config
handle_select_config(packet)
when :add_config
handle_add_config(packet)
when :update_config # rename config/file
handle_update_config(packet)
when :delete_config
handle_delete_config(packet)
else
log.d(TAG, "No hand off available for packet type: #{packet.type}")
end
@@ -45,11 +57,15 @@ module TAC
# TODO: Handle errors
def handle_error(packet)
if @host_is_a_connection
title, message = packet.body.split(Packet::PROTOCOL_SEPERATOR, 2)
$window.push_state(TAC::Dialog::TACNETDialog, title: title, message: message)
end
end
def handle_upload_config(packet)
begin
config_name, json = packet.body.split(Packet::PROTOCOL_HEADER_SEPERATOR)
config_name, json = packet.body.split(Packet::PROTOCOL_SEPERATOR, 2)
data = JSON.parse(json, symbolize_names: true)
if @host_is_a_connection
@@ -58,11 +74,15 @@ module TAC
$window.push_state(TAC::Dialog::AlertDialog, title: "Invalid Config", message: "Remote config to old.")
elsif data.is_a?(Hash) && data.dig(:config, :spec_version) == TAC::CONFIG_SPEC_VERSION
$window.push_state(TAC::Dialog::ConfirmDialog, title: "Replace Config", message: "Replace local config\nwith remote config?", callback_method: proc {
File.open("#{TAC::CONFIGS_PATH}/#{config_name}.json", "w") { |f| f.write json }
$window.backend.load_config(config_name)
})
if $window.backend.config.name == config_name
$window.backend.load_config(config_name)
$window.instance_variable_get(:"@states").each do |state|
state.populate_groups_list if state.is_a?(TAC::States::Editor)
end
end
elsif data.is_a?(Hash) && data.dig(:config, :spec_version) < TAC::CONFIG_SPEC_VERSION
# OLD CONFIG, Upgrade?
@@ -103,6 +123,56 @@ module TAC
end
end
def handle_list_configs(packet)
if @host_is_a_connection # Download new or updated configs
list = packet.body.split(Packet::PROTOCOL_SEPERATOR).map { |part| part.split(",") }
remote_configs = list.map { |l| l.first }
local_configs = Dir.glob("#{TAC::CONFIGS_PATH}/*.json").map { |f| File.basename(f, ".json") }
_diff = local_configs - remote_configs
list.each do |name, revision|
revision = Integer(revision)
path = "#{TAC::CONFIGS_PATH}/#{name}.json"
if File.exist?(path)
config = Config.new(name)
if config.configuration.revision < revision
$window.backend.tacnet.puts( PacketHandler.packet_download_config(name) )
elsif config.configuration.revision > revision
$window.backend.tacnet.puts( PacketHandler.packet_upload_config(name, JSON.dump( config )) )
end
else
$window.backend.tacnet.puts( PacketHandler.packet_download_config(name) )
end
end
_diff.each do |name|
config = Config.new(name)
$window.backend.tacnet.puts( PacketHandler.packet_upload_config(name, JSON.dump( config )) )
end
else
if $server.active_client && $server.active_client.connected?
$server.active_client.puts(PacketHandler.packet_list_configs)
end
end
end
def handle_select_config(packet)
end
def handle_add_config(packet)
end
def handle_update_config(packet)
end
def handle_delete_config(packet)
end
def self.packet_handshake(client_uuid)
Packet.create(Packet::PACKET_TYPES[:handshake], client_uuid)
end
@@ -120,10 +190,24 @@ module TAC
end
def self.packet_upload_config(config_name, json)
string = "#{config_name}#{Packet::PROTOCOL_HEADER_SEPERATOR}#{json.gsub("\n", " ")}"
string = "#{config_name}#{Packet::PROTOCOL_SEPERATOR}#{json.gsub("\n", " ")}"
Packet.create(Packet::PACKET_TYPES[:upload_config], string)
end
def self.packet_list_configs
files = Dir.glob("#{TAC::CONFIGS_PATH}/*.json")
list = files.map do |file|
name = File.basename(file, ".json")
config = Config.new(name)
"#{name},#{config.configuration.revision}"
end.join(Packet::PROTOCOL_SEPERATOR)
Packet.create(
Packet::PACKET_TYPES[:list_configs],
list
)
end
end
end
end
end

View File

@@ -71,11 +71,9 @@ module TAC
@active_client = client
# TODO: Backup local config
# SEND CONFIG
settings = TAC::Settings.new
config = File.read("#{TAC::CONFIGS_PATH}/#{settings.config}.json")
@active_client.puts(PacketHandler.packet_handshake(@active_client.uuid))
@active_client.puts(PacketHandler.packet_upload_config(settings.config, config))
@active_client.puts(PacketHandler.packet_list_configs)
log.i(TAG, "Client connected!")
@@ -137,4 +135,4 @@ module TAC
end
end
end
end
end