mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-06-11 01:04:56 +02:00
fix(console): multi-byte hops in change_path parser and path display
The console treated 2-/3-byte hops as 1-byte: - change_path "<name>" d103 5e34 (space-separated) was joined into continuous hex with hash_size=1, producing four 1-byte hops instead of two 2-byte ones. - path <name> always rendered 1-byte hops because it decoded the hash-size mode from upper bits of out_path_len. In meshcore 2.x the library already masks out_path_len to the hop count and exposes the mode separately in out_path_hash_mode. Parser now splits on commas, whitespace, or arrow separators and requires consistent hop length. Display reads out_path_hash_mode and also shows the byte size, e.g. "D103,5E34 (2 hops, 2B)".
This commit is contained in:
@@ -2753,7 +2753,7 @@ class DeviceManager:
|
||||
return {'success': True, 'data': {
|
||||
'out_path': contact.get('out_path', ''),
|
||||
'out_path_len': contact.get('out_path_len', -1),
|
||||
'out_path_hash_len': contact.get('out_path_hash_len', 0),
|
||||
'out_path_hash_mode': contact.get('out_path_hash_mode', 0),
|
||||
}}
|
||||
|
||||
def discover_path(self, name_or_key: str) -> Dict:
|
||||
|
||||
+19
-12
@@ -807,14 +807,15 @@ def _execute_console_command(args: list) -> str:
|
||||
data = result['data']
|
||||
opl = data.get('out_path_len', -1)
|
||||
raw = data.get('out_path', '')
|
||||
hash_mode = data.get('out_path_hash_mode', 0)
|
||||
if opl > 0:
|
||||
hop_count = opl & 0x3F
|
||||
hash_size = (opl >> 6) + 1
|
||||
meaningful = raw[:hop_count * hash_size * 2]
|
||||
hop_count = opl
|
||||
hash_size = max(1, hash_mode + 1) if hash_mode >= 0 else 1
|
||||
chunk = hash_size * 2
|
||||
meaningful = raw[:hop_count * chunk]
|
||||
hops = [meaningful[i:i+chunk].upper() for i in range(0, len(meaningful), chunk)]
|
||||
path_str = ','.join(hops) if hops else f'len:{opl}'
|
||||
return f"Path to {name}: {path_str} ({hop_count} hops)"
|
||||
return f"Path to {name}: {path_str} ({hop_count} hops, {hash_size}B)"
|
||||
elif opl == 0:
|
||||
return f"Path to {name}: Direct"
|
||||
else:
|
||||
@@ -852,17 +853,23 @@ def _execute_console_command(args: list) -> str:
|
||||
if result.get('success'):
|
||||
return result.get('message', 'OK')
|
||||
return f"Error: {result.get('error')}"
|
||||
if ',' in raw:
|
||||
chunks = [c.strip() for c in raw.split(',') if c.strip()]
|
||||
first_len = len(chunks[0]) if chunks else 0
|
||||
if first_len in (2, 4, 6):
|
||||
hash_size = first_len // 2
|
||||
else:
|
||||
# Split on commas, whitespace, or arrow separators. Each chunk = one hop.
|
||||
norm = raw.replace('→', ' ').replace('->', ' ')
|
||||
chunks = [c for c in re.split(r'[,\s]+', norm) if c]
|
||||
if len(chunks) >= 2:
|
||||
first_len = len(chunks[0])
|
||||
if first_len not in (2, 4, 6):
|
||||
return "Error: hop must be 1, 2, or 3 bytes (2/4/6 hex chars)"
|
||||
if any(len(c) != first_len for c in chunks):
|
||||
return "Error: all hops must have the same length"
|
||||
hash_size = first_len // 2
|
||||
path_hex = ''.join(chunks)
|
||||
else:
|
||||
path_hex = raw.replace(' ', '').replace('→', '').replace('->', '')
|
||||
elif len(chunks) == 1:
|
||||
# Single chunk: continuous hex, assume 1-byte hops
|
||||
path_hex = chunks[0]
|
||||
hash_size = 1
|
||||
else:
|
||||
return "Error: empty path"
|
||||
try:
|
||||
bytes.fromhex(path_hex)
|
||||
except ValueError:
|
||||
|
||||
Reference in New Issue
Block a user