#!/usr/bin/env python3 """Dump raw bytes around first action mapping to understand binary structure""" import sys sys.path.insert(0, r'C:\DEV\COPILOT\geutebruck-api\src\api') import grpc from protos import configuration_pb2 from protos import configuration_pb2_grpc def dump_binary_structure(): """Get first action mapping and dump its bytes""" print("Connecting to SDK Bridge...") with grpc.insecure_channel('localhost:50051') as channel: stub = configuration_pb2_grpc.ConfigurationServiceStub(channel) # Get action mappings first to find offsets request = configuration_pb2.ReadActionMappingsRequest() response = stub.ReadActionMappings(request) if not response.success or not response.mappings: print("Failed to get mappings") return False # Get first 3 mappings for i, mapping in enumerate(response.mappings[:3]): print(f"\n{'='*80}") print(f"Mapping {i+1}: offset {mapping.start_offset} to {mapping.end_offset} ({mapping.end_offset - mapping.start_offset} bytes)") # Show old format actions print(f"Old format actions ({len(mapping.actions)}):") for j, action in enumerate(mapping.actions): try: print(f" [{j}] {action}") except: print(f" [{j}] (decode error)") # Now get the full configuration to access raw binary print("\n" + "="*80) print("Getting full configuration to examine binary structure...") full_request = configuration_pb2.ReadConfigurationRequest() full_response = stub.ReadConfiguration(full_request) if not full_response.success: print("Failed to get full configuration") return False print(f"Got {len(full_response.nodes)} nodes") # Find the "ules" markers ules_markers = [i for i, n in enumerate(full_response.nodes) if n.node_type == "marker" and "ules" in (n.name or "")] print(f"Found {len(ules_markers)} ules markers") # Examine first 3 for i, marker_idx in enumerate(ules_markers[:3]): marker = full_response.nodes[marker_idx] print(f"\n{'-'*80}") print(f"Marker {i+1} at index {marker_idx}, offset {marker.start_offset}:") # Show marker name (first 200 chars) try: name_hex = ' '.join(f'{ord(c):02X}' for c in marker.name[:50]) name_ascii = ''.join(c if 32 <= ord(c) < 127 else '.' for c in marker.name[:100]) print(f" Name (hex): {name_hex}") print(f" Name (ascii): {name_ascii}") except: print(f" Name: (decode error)") # Look at surrounding nodes print(f"\n Surrounding nodes (5 before, 20 after):") start_idx = max(0, marker_idx - 5) end_idx = min(len(full_response.nodes), marker_idx + 20) for j in range(start_idx, end_idx): node = full_response.nodes[j] prefix = ">>>" if j == marker_idx else " " # Show node details try: name_display = (node.name[:30] + "...") if len(node.name or "") > 30 else (node.name or "") value_display = str(node.value)[:40] if node.value else "" print(f"{prefix} [{j:4d}] offset={node.start_offset:6d}, type={node.node_type:8s}, name={name_display!r:35s}, value={value_display!r}") except: print(f"{prefix} [{j:4d}] offset={node.start_offset:6d}, type={node.node_type:8s} (decode error)") return True if __name__ == '__main__': dump_binary_structure()