mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-11 19:17:04 +10:00
79 lines
2.3 KiB
Dart
79 lines
2.3 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import '../models/contact.dart';
|
|
import '../connector/meshcore_protocol.dart';
|
|
|
|
class PathHelper {
|
|
static String formatPathHex(List<int> pathBytes) {
|
|
return pathBytes
|
|
.map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase())
|
|
.join(',');
|
|
}
|
|
|
|
static String formatHopHex(List<int> hopBytes) {
|
|
return hopBytes
|
|
.map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase())
|
|
.join();
|
|
}
|
|
|
|
static List<Uint8List> splitPathBytes(List<int> pathBytes, int hashByteWidth) {
|
|
if (pathBytes.isEmpty) return const [];
|
|
|
|
final width = hashByteWidth.clamp(1, 4);
|
|
final hops = <Uint8List>[];
|
|
for (int i = 0; i < pathBytes.length; i += width) {
|
|
final endIdx = (i + width).clamp(0, pathBytes.length);
|
|
final hopBytes = pathBytes.sublist(i, endIdx);
|
|
if (hopBytes.isNotEmpty) {
|
|
hops.add(Uint8List.fromList(hopBytes));
|
|
}
|
|
}
|
|
return hops;
|
|
}
|
|
|
|
/// Resolves path bytes to contact names, supporting multi-byte hash widths.
|
|
|
|
/// Groups path bytes according to [hashByteWidth]:
|
|
/// - 1: Single byte per hop (256 unique nodes)
|
|
/// - 2: Two bytes per hop (65K unique nodes)
|
|
/// - 3: Three bytes per hop (16M unique nodes)
|
|
/// - 4: Four bytes per hop (4.3G unique nodes)
|
|
static String resolvePathNames(
|
|
List<int> pathBytes,
|
|
List<Contact> allContacts,
|
|
int hashByteWidth,
|
|
) {
|
|
if (pathBytes.isEmpty) return '';
|
|
|
|
final parts = <String>[];
|
|
|
|
for (final hopBytes in splitPathBytes(pathBytes, hashByteWidth)) {
|
|
final hex = formatHopHex(hopBytes);
|
|
|
|
// Find matching contacts by comparing public key prefix
|
|
final matches = allContacts
|
|
.where((c) {
|
|
if (c.publicKey.length < hopBytes.length) return false;
|
|
if (c.type != advTypeRepeater && c.type != advTypeRoom) return false;
|
|
// Compare bytes using listEquals for multi-byte support
|
|
return listEquals(
|
|
c.publicKey.sublist(0, hopBytes.length),
|
|
hopBytes,
|
|
);
|
|
})
|
|
.toList();
|
|
|
|
if (matches.isEmpty) {
|
|
parts.add(hex);
|
|
} else if (matches.length == 1) {
|
|
parts.add(matches.first.name);
|
|
} else {
|
|
parts.add(matches.map((c) => c.name).join(' | '));
|
|
}
|
|
}
|
|
|
|
return parts.join(' \u2192 ');
|
|
}
|
|
}
|