From 5657892887f12af260918e821b340625069a894b Mon Sep 17 00:00:00 2001 From: lepshiy Date: Sat, 1 Nov 2025 15:21:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A2=D1=80=D0=B0=D1=81=D1=81=D0=B0=20-=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D1=81=D1=82=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scenes/diagram/diagram.gd | 7 ++ scenes/tilemap/23900.png | Bin 3194 -> 2725 bytes scenes/tilemap/ship_mark.tscn | 2 +- scenes/работа/работа.gd | 20 +++-- scripts/settings.gd | 2 +- scripts/signaller.gd | 6 ++ scripts/trassa.gd | 160 +++++++++++++++++++++++++++++----- 7 files changed, 167 insertions(+), 30 deletions(-) diff --git a/scenes/diagram/diagram.gd b/scenes/diagram/diagram.gd index d0a346d..97d5035 100644 --- a/scenes/diagram/diagram.gd +++ b/scenes/diagram/diagram.gd @@ -78,6 +78,13 @@ func set_seczap(id: int, szv: Vector4): seczap.set_instance_shader_parameter('radius', sv(szv.x)) +func clear_all_seczap(): + for child in get_children(): + if child.name.begins_with("SECZAP"): + remove_child(child) + child.queue_free() + + func set_seczap_color(id: int, color: Color): var seczap: = get_node('SECZAP%d' % id) seczap.set_instance_shader_parameter('color', color) diff --git a/scenes/tilemap/23900.png b/scenes/tilemap/23900.png index b7ca1d1b35a14b34b23e70ce0a9521dd76f3ec1e..f8e3ab019d8585150210aa6a8c5b43ad9506439f 100644 GIT binary patch literal 2725 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 void: @@ -25,14 +45,95 @@ class Trassa extends unit.Unit: interfer.connect('interfer_resized', Callable(self, 'on_interfer_resized')) - # Обработка полученного пакета + # Обработка полученного пакета - определение типа func parse(rx_data: PackedByteArray, tick: int): rx_tick = tick if not online: online = true emit_signal('line_changed', self) + data_type = detect_data(rx_data) + if data_type == "json": + parse_json(rx_data) + elif data_type == "binary": + parse_byte(rx_data) + else: + emit_signal('parse_failed', self) + + + # Определение типа данных + func detect_data(data: PackedByteArray) -> String: + if data.size() > 0: + var first_char = data[0] + if first_char == 123 or first_char == 91: + return "json" + if data.size() >= 2: + var potential_json = data.slice(0, min(100, data.size())) + var test_string = potential_json.get_string_from_ascii() + if test_string and (test_string.begins_with("{") or test_string.begins_with("[")): + return "json" + return "binary" + + + # Обработка JSON данных + func parse_json(rx_data: PackedByteArray) -> void: + var json_string = rx_data.get_string_from_utf8() + if json_string: + if Error.OK == json_conv.parse(json_string): + json_dic = json_conv.get_data() + target = check_target(json_dic) + sector_draw(json_dic) + emit_signal('data_received', self) + else: + var msg = json_conv.get_error_message() + emit_signal('parse_failed', self) + else: + emit_signal('parse_failed', self) + + + func sector_draw(data: Dictionary) -> void: + var sector_data = { + "draw": false, + "color": Color.GREEN * Color(1, 1, 1, 0.1), + "rect": Rect2(), + "index": 0 } + if data.get("clean_all", false) == true: + current_index = 0 + signaller.emit_signal('clear_klaster') + return + if data.has("txe") and data.has("rxe"): + var txe = data["txe"] + var rxe = data["rxe"] + if txe == true or rxe == true: + sector_data["draw"] = true + if data.has("lfb") and data.has("hfb") and data.has("dap") and data.has("daa"): + var lfb = int(data["lfb"]) + var hfb = int(data["hfb"]) + var dap = int(data["dap"]) + var daa = int(data["daa"]) + var key = str(lfb) + "_" + str(hfb) + for i in range(set_klaster.size()): + var mapping = set_klaster[i] + if lfb == mapping[0] and hfb == mapping[1]: + lfb = mapping[2] + hfb = mapping[3] + break + sector_data["rect"] = Rect2(lfb, daa, dap, hfb) + sector_data["index"] = sector_index() + signaller.emit_signal('sector_klaster', sector_data) + + + func sector_index() -> int: + current_index += 1 + return current_index - 1 + + + # Обработка бинарных данных + func parse_byte(rx_data: PackedByteArray): var words: Array[int] = [] var offset: int = 0 + if rx_data.size() < 40: + emit_signal('parse_failed', self) + return while offset < rx_data.size(): if offset + 4 <= rx_data.size(): var word = rx_data.decode_u32(offset) @@ -42,6 +143,7 @@ class Trassa extends unit.Unit: break if words.size() < 10: emit_signal('parse_failed', self) + return tx_stack.fill(NOINFO) tx_stack[0] = words[0] # ID tx_stack[1] = msg_counter # Nc @@ -58,6 +160,28 @@ class Trassa extends unit.Unit: emit_signal("data_received", self) + # Проверка на нужный JSON файл + func check_target(data, current_path: String = "root") -> bool: + if data == null: + return false + if data is int or data is float: + if int(data) == 21930: + return true + return false + var found = false + if data is Dictionary: + for key in data: + var new_path = current_path + "." + str(key) + if check_target(data[key], new_path): + found = true + elif data is Array: + for i in range(data.size()): + var new_path = current_path + "[" + str(i) + "]" + if check_target(data[i], new_path): + found = true + return found + + func interfer_data() -> void: for i in range(67, 74): tx_stack[i] = 0 @@ -79,7 +203,6 @@ class Trassa extends unit.Unit: return NOINFO - # Отправка пакета от uarep-ctl func process(now_tick: int) -> int: if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT): online = false @@ -99,32 +222,32 @@ class Trassa extends unit.Unit: return Error.ERR_BUSY - # CRC вычисление + # Контрольная сумма func _calc_crc(data: Array) -> int: var acc: int = 0 - for i in range(data.size() - 1): # кроме CRC + for i in range(data.size() - 1): if i in [0, 1]: continue acc = (acc + (data[i] & 0xFFFFFFFF)) & 0xFFFFFFFF return acc - # Обновление всех активных помех - func on_interfer_resized(ecms_dic: Dictionary) -> void: ecms = ecms_dic + func on_interfer_resized(ecms_dic: Dictionary) -> void: + ecms = ecms_dic func interfer_uarep() -> void: - tx_stack[65] = 0 - tx_stack[66] = 0 - for ecm in ecms.values(): - if ecm.krp == 'srni' and ecm.svk == 1: - tx_stack[65] = 1 - if ecm.krp == 'svi1' and ecm.svk == 1: - tx_stack[66] = 1 - tx_stack[1] = msg_counter + tx_stack[65] = 0 + tx_stack[66] = 0 + for ecm in ecms.values(): + if ecm.krp == 'srni1' and ecm.svk == 1: + tx_stack[65] = 1 + if ecm.krp == 'svi1' and ecm.svk == 1: + tx_stack[66] = 1 + tx_stack[1] = msg_counter - # Обработка указаний от Трассы по кнопке + # Выполнение указаний по кнопке Трасса func btn_trassa_pressed() -> void: var state = ProjectSettings.get_setting('application/config/Внешнее указание Трасса', false) if state == true: @@ -156,8 +279,3 @@ class Trassa extends unit.Unit: ecm.krp = interfer.INTERFER_OFF interfer.send_ecm(ecm, unit_caps) signaller.emit_signal('interfer_off', ecm) - for ecm in ecms.values(): - if ecm.krp == 'svi1' and ecm.svk == 1: - ecm.krp = interfer.INTERFER_OFF - interfer.send_ecm(ecm, unit_caps) - signaller.emit_signal('interfer_off', ecm)