Files
imi_skysens/threats.gd

470 lines
18 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Node
var id_array: Array # Массив id целей
var treats : Dictionary # Словарь целей
var msg_counter : int = 0 # Счётчик отправленных пакетов
var g_table: GridContainer
const TableCellType1 = preload('res://ячейка-1.tscn')
const TableCellType2 = preload('res://кнопка-3.tscn')
const TableCellType3 = preload('res://кнопка-4.tscn')
const TableCellType4 = preload('res://заголовок.tscn')
const TableCellType5 = preload('res://ячейка-2.tscn')
const TableCellType6 = preload('res://кнопка-5.tscn')
const TableHeader = preload('res://table/header.tscn')
# Индекс колонки: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const TABLE_HEADERS = ['ID Цели', 'Курc.град', 'Частота', 'Ш. диап.', 'Ампл.', 'T обновл.', 'Мод.', 'Реж. см. F', 'Ск. пер.', 'Протокол', 'Ст. дол.', 'Ст. шир.', 'Cт. выс.', 'Тек. дол.', 'Тек. шир.', 'Тек. выс.', ]
const TABLE_HEADER_TYPES = [ TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader]
const TABLE_HEADER_ALIGNMENTS = [ HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
const TABLE_ROW_TYPES = [ TableCellType1, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType6, TableCellType6, TableCellType5, TableCellType6, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType5, TableCellType5]
const TABLE_ROW_ALIGNMENTS = [ HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
const TABLE_COLUMN_SIZES = [ 82, 82, 82, 82, 82, 90, 150, 150, 80, 150, 82, 82, 82, 82, 82, 82]
const COLUMN_ID = 0 # Идентификатор цели
const COLUMN_AOA = 1 # Курсовой угол на источник сигнала, градусы
const COLUMN_FREQ = 2 # Частота несущей или центральная частота, МГц
const COLUMN_WIDTH = 3 # Ширина занимаемого диапазона частот, МГц
const COLUMN_POW = 4 # Уровень принимаемого сигнала, дБ
const COLUMN_TICK = 5 # Относительное время обнаружения сигнала, мс.
const COLUMN_TMOD = 6 # Вид модуляции
const COLUMN_FREQM = 7 # Режим смены частоты.
const COLUMN_BAUD = 8 # Скорость передачи данных, бит/с
const COLUMN_PROTO = 9 # Тип протокола источника сигнала.
const COLUMN_SLON = 10 # Координаты старта, долгота в градусах
const COLUMN_SLAT = 11 # Координаты старта, широта в градусах
const COLUMN_SALT = 12 # Координаты старта, высота от уровня моря, метры
const COLUMN_LAT = 13 # Текущие координаты, долгота в градусах
const COLUMN_LON = 14 # Текущие координаты, широта в градусах
const COLUMN_ALT = 15 # Текущая высота, метры
# Индексы колонок, которым можно задавать выравнивание текста
const TABLE_ALLIGNED_COLUMNS = [
COLUMN_ID,
COLUMN_AOA,
COLUMN_FREQ,
COLUMN_WIDTH,
COLUMN_POW,
COLUMN_TICK,
COLUMN_BAUD,
COLUMN_SLON,
COLUMN_SLAT,
COLUMN_SALT,
COLUMN_LAT,
COLUMN_LON,
COLUMN_ALT ]
# Индексы колонок, в которых можно вводит текст
const TABLE_ENTRY_COLUMNS = [
COLUMN_AOA,
COLUMN_FREQ,
COLUMN_WIDTH,
COLUMN_POW,
COLUMN_TICK,
COLUMN_BAUD,
COLUMN_SLON,
COLUMN_SLAT,
COLUMN_SALT,
COLUMN_LAT,
COLUMN_LON,
COLUMN_ALT ]
# Типы модуляции
const MODE_TYPES = ['<неопр.>', 'am', 'ook', 'ask', 'fm', 'qpsk', 'oqpsk', 'pi4qpsk', 'qam16',
'qam32', 'qam64', 'qam128', 'qam256', 'qam512', 'fsk', 'cpfsk', 'psk','ofdm']
# Режим смены частоты
const FREQM = ['<неопр.>', 'fhss', 'lfm', 'const']
# Протоколы радиомодема
const M_PROTO = ['<неопр.>', '3dlink', 'skyhopperpro', 'picardiooem', 'solo7', 'j11',
'mavlink', 'ltm', 'hc12', 'df1', ]
# Номера колонок
const COLUMN_OPT = [[COLUMN_TMOD, MODE_TYPES], [COLUMN_FREQM, FREQM], [COLUMN_PROTO, M_PROTO]]
const COLUMN_OPT_BTN = [COLUMN_TMOD, COLUMN_FREQM, COLUMN_PROTO]
const ID_ARRAY_LEN = 100 # Размер пула номеров целей
# Цель
class Threat:
# параметры цели, второе значение, разрешение отправки.
var row: Dictionary = {
'id':[0,true],
'aoa':[10.0,true],
'freq':[2480.0,true],
'width':[20.0,true],
'power':[20.0,true],
'tick':[10,true],
'tmod':['<неопр.>',false],
'freqm':['<неопр.>',false],
'baud':[0.0,false],
'proto':['<неопр.>',false],
'slon':[0.0,false],
'slat':[0.0,false],
'salt':[0.0,false],
'lat':[0.0,false],
'lon':[0.0,false],
'alt':[0.0,false],
}
var row_id: int
func _init(th_id : int, row_i: int):
row.id[0] = th_id
row_id = row_i
func get_data():
var data_to_send : Dictionary
for key in row.keys():
var value = row[key]
var data = value[0]
var need_send = value[1]
if need_send:
data_to_send[key] = data
return data_to_send
func update_rows():
var new_rows: Array = []
new_rows.append(_check_value(row.id))
new_rows.append(_check_value(row.aoa))
new_rows.append(_check_value(row.freq))
new_rows.append(_check_value(row.width))
new_rows.append(_check_value(row.power))
new_rows.append(_check_value(row.tick))
new_rows.append(_check_value(row.tmod))
new_rows.append(_check_value(row.freqm))
new_rows.append(_check_value(row.baud))
new_rows.append(_check_value(row.proto))
new_rows.append(_check_value(row.slon))
new_rows.append(_check_value(row.slat))
new_rows.append(_check_value(row.salt))
new_rows.append(_check_value(row.lat))
new_rows.append(_check_value(row.lon))
new_rows.append(_check_value(row.alt))
return new_rows
func _check_value(val):
if val[1]:
return '%s' % val[0]
else:
return ''
func set_aoa(val):
var value = float(val)
value = Tools.check_low_high(value, 0, 360)
value = Tools.check_len(val, value)
row.aoa[0] = value
row.aoa[1] = Tools.check_empty(value)
return value
func set_freq(val):
var value = float(val)
value = Tools.check_negative(value)
value = Tools.check_len(val, value)
row.freq[0] = value
row.freq[1] = Tools.check_empty(value)
return value
func set_width(val):
var value = float(val)
value = Tools.check_negative(value)
value = Tools.check_len(val, value)
row.width[0] = value
row.width[1] = Tools.check_empty(value)
return value
func set_power(val):
var value = float(val)
value = Tools.check_negative(value)
value = Tools.check_len(val, value)
row.power[0] = value
row.power[1] = Tools.check_empty(value)
return value
func set_tick(val):
var value = int(val)
value = Tools.check_low_high(value, 0, 60000)
value = Tools.check_len(val, value)
row.tick[0] = value
row.tick[1] = Tools.check_empty(value)
return value
func set_baud(val):
var value = float(val)
value = Tools.check_negative(value)
value = Tools.check_len(val, value)
row.baud[0] = value
row.baud[1] = Tools.check_empty(value)
return value
func set_slon(val):
var value = float(val)
value = Tools.check_low_high(value, -90, 90)
value = Tools.check_len(val, value)
row.slon[0] = value
row.slon[1] = Tools.check_empty(value)
return value
func set_slat(val):
var value = float(val)
value = Tools.check_low_high(value, -180, 180)
value = Tools.check_len(val, value)
row.slat[0] = value
row.slat[1] = Tools.check_empty(value)
return value
func set_salt(val):
var value = float(val)
value = Tools.check_len(val, value)
row.salt[0] = value
row.salt[1] = Tools.check_empty(value)
return value
func set_lon(val):
var value = float(val)
value = Tools.check_low_high(value, -90, 90)
value = Tools.check_len(val, value)
row.lon[0] = value
row.lon[1] = Tools.check_empty(value)
return value
func set_lat(val):
var value = float(val)
value = Tools.check_low_high(value, -180, 180)
value = Tools.check_len(val, value)
row.lat[0] = value
row.lat[1] = Tools.check_empty(value)
return value
func set_alt_pressed(val):
var value = float(val)
value = Tools.check_len(val, value)
row.alt[0] = value
row.alt[1] = Tools.check_empty(value)
return value
func set_tmod(val):
var value = str(val)
row.tmod[0] = value
row.tmod[1] = false if value == '<неопр.>' else true
return value
func set_freqm(val):
var value = str(val)
row.freqm[0] = value
row.freqm[1] = false if value == '<неопр.>' else true
return value
func set_proto(val):
var value = str(val)
row.proto[0] = value
row.proto[1] = false if value == '<неопр.>' else true
return value
func init_treats(table, btn_add, btn_del, btn_save): # Инициализация вкладки с целями
for i in range(ID_ARRAY_LEN): # Заполняет массив ID целей
id_array.append(i+1)
table.set_header(TABLE_HEADER_TYPES)
table.set_header_text(TABLE_HEADERS)
load_treats(table)
init_table(table, TABLE_COLUMN_SIZES)
g_table = table
table.set_columns_min_size(TABLE_COLUMN_SIZES)
table.connect('row_pressed', Callable(self, 'on_row_pressed').bind(table))
table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, [])
btn_add.connect('button_up', Callable(self, 'on_btn_add').bind(table))
btn_del.connect('button_up', Callable(self, 'on_btn_del').bind(table))
btn_save.connect('button_up', Callable(self, 'on_btn_save'))
func load_treats(table):
var file = FileAccess.open('user://save.json', FileAccess.READ)
if file == null:
return
var read = file.get_as_text()
file.close()
var json_conv: = JSON.new()
if Error.OK == json_conv.parse(read):
var json_data = json_conv.get_data()
for item in json_data:
if item.has('id'):
var id = item['id']
id_array.erase(int(id))
var threat : = Threat.new(id, table.get_rows_count())
treats['%d' % id] = threat
for key in item:
threat.row[key] = [item[key], true]
var row = threat.update_rows()
table.add_row(TABLE_ROW_TYPES)
table.set_row_text(table.get_rows_count()-1, row)
table.set_node_user_data(0, table.get_rows_count()-1, threat)
init_opt_btns(table.get_rows_count()-1, table, threat)
table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, [])
func on_btn_save():
var file = FileAccess.open('user://save.json', FileAccess.WRITE)
var data_to_json : Array
for key in treats:
var treat = treats[key]
var data = treat.get_data()
data_to_json.append(data)
var json = JSON.new().stringify(data_to_json)
file.store_string(json)
file.close()
func init_table(table: Table, sizes: Array):
for i_row in table.get_rows_count():
pass
func init_opt_btns(row : int, table, threat):
for item in COLUMN_OPT:
var i: int = 0
var i_col = item[0]
var opt_arr = item[1]
var cell = table.get_node2(i_col, row)
for opt in opt_arr:
cell.add_item(opt)
if i_col == COLUMN_TMOD:
var mode = threat.row['tmod'][0]
i = MODE_TYPES.find(mode)
if i_col == COLUMN_FREQM:
var freqm = threat.row['freqm'][0]
i = FREQM.find(freqm)
if i_col == COLUMN_PROTO:
var proto = threat.row['proto'][0]
i = M_PROTO.find(proto)
cell.select(i)
func on_item_selected(item_num, node):
var optbtn_text = node[0].text
var indexis = g_table.get_key_indexes(node[0].name)
var row_i = indexis[1]
var col_i = indexis[0]
var cell = g_table.get_node2(0,row_i)
var value = set_value(optbtn_text, cell.text, col_i)
func on_edit_entry(text : String, entry):
var indexis = g_table.get_key_indexes(entry[0].name)
var row_i = indexis[1]
var col_i = indexis[0]
var cell = g_table.get_node2(0,row_i)
var value = set_value(text, cell.text, col_i)
entry[0].text = str(value)
func set_value(val : String, treat_id : String, column : int):
var treat = treats[treat_id]
match column:
COLUMN_AOA:
return treat.set_aoa(val)
COLUMN_FREQ:
return treat.set_freq(val)
COLUMN_WIDTH:
return treat.set_width(val)
COLUMN_POW:
return treat.set_power(val)
COLUMN_TICK:
return treat.set_tick(val)
COLUMN_TMOD:
return treat.set_tmod(val)
COLUMN_FREQM:
return treat.set_freqm(val)
COLUMN_BAUD:
return treat.set_baud(val)
COLUMN_PROTO:
return treat.set_proto(val)
COLUMN_SLON:
return treat.set_slon(val)
COLUMN_SLAT:
return treat.set_slat(val)
COLUMN_SALT:
return treat.set_salt(val)
COLUMN_LAT:
return treat.set_lon(val)
COLUMN_LON:
return treat.set_lat(val)
COLUMN_ALT:
return treat.set_alt_pressed(val)
func on_row_pressed(i_row: int, table):
table.clear_rows_selected()
table.set_row_selected(i_row, true)
func on_btn_add(table):
var id = pop_id()
var threat : = Threat.new(id, table.get_rows_count())
treats['%d' % id] = threat
var row = threat.update_rows()
table.add_row(TABLE_ROW_TYPES)
table.set_row_text(table.get_rows_count()-1, row)
table.set_node_user_data(0, table.get_rows_count()-1, threat)
init_opt_btns(table.get_rows_count()-1, table, threat)
table.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
table.connect_columns(self, 'item_selected', 'on_item_selected', COLUMN_OPT_BTN, [])
func on_btn_del(table):
var row_i = []
table.get_selected_rows(row_i)
if len(row_i) > 0:
var cell = table.get_node2(0, row_i[0])
treats.erase(cell.text)
table.remove_row(row_i[0])
for i in table.get_rows_count():
var treat = table.get_node_user_data(0, i)
treat.row_id = i
func pop_id():
var id = 0
if len(id_array):
id = id_array[0]
id_array.remove_at(0)
return id
func push_id(id : int):
id_array.append(id)
func get_threats_data():
var data_to_json : Dictionary
data_to_json['ts'] = 5
msg_counter += 1
data_to_json['ss'] = msg_counter
data_to_json['msvk'] = []
for item in Interfers.interfers.values():
var msvk = {}
msvk['ispp'] = item.options['ispp']
msvk['svk'] = item.svk
data_to_json['msvk'].append(msvk)
data_to_json['mis'] = []
for key in treats:
var treat = treats[key]
set_ticks(treat)
var data = treat.get_data()
data_to_json['mis'].append(data)
var json = JSON.new().stringify(data_to_json)
var pac = json.to_utf8_buffer()
return pac
func set_ticks(treat):
var tick = Time.get_ticks_msec()
var cell = g_table.get_node2(COLUMN_TICK, treat.row_id)
cell.text = str(treat.set_tick(str(tick%60000)))