diff --git a/src/chat/chat_status.c b/src/chat/chat_status.c index 54b0ed7c..689b7c9c 100644 --- a/src/chat/chat_status.c +++ b/src/chat/chat_status.c @@ -301,15 +301,15 @@ void chat_core_collect_conn_metrics_trampoline(void* arg) { } /* ── Live-снапшот для панели деталей участника ── - * packet: [node_id:8][flags:1][own_tcp_active:2][link_count:1](link:24B)*[sock_count:1](sock:48B)* - * flags: bit0=conn_present bit1=conn_up(links_up) bit2=conn_initialized bit3=client bit4=server - * link: [is_tcp:1][link_state:1][link_status:1][tcp_ready:1][family:1][addr_len:1][addr:16][port:2] + * packet: [node_id:8][flags:1][own_tcp_active:2][link_count:1](link:25B)*[sock_count:1](sock:48B)* + * flags: bit0=conn_present bit1=conn_up(links_up) bit2=conn_initialized + * link: [is_tcp:1][link_state:1][link_status:1][tcp_ready:1][is_server:1][family:1][addr_len:1][addr:16][port:2] * sock: [sock_id:4][port:2][link_count:4][ifname:38] * Собирается в worker-потоке — читает живые структуры UTUN_INSTANCE безопасно. */ #define MEMBER_DETAIL_MAX_LINKS 16 #define MEMBER_DETAIL_MAX_SOCKS 16 -#define MEMBER_DETAIL_LINK_SIZE 24 +#define MEMBER_DETAIL_LINK_SIZE 25 #define MEMBER_DETAIL_SOCK_SIZE 48 /* Повторяет Qt: name.lastIndexOf("_v") → name.mid(3, idx - 3) */ @@ -337,10 +337,6 @@ static void collect_member_detail(uint64_t node_id) { flags |= 1; if (conn->links_up) flags |= 2; if (conn->initialized) flags |= 4; - if (conn->links) { - if (!conn->links->is_server) flags |= 8; - else flags |= 16; - } } uint16_t own_tcp_active = 0; @@ -388,6 +384,7 @@ static void collect_member_detail(uint64_t node_id) { *p++ = lk->link_state; *p++ = lk->link_status; *p++ = (lk->is_tcp && lk->tcp_link && stcp_link_is_ready(lk->tcp_link)) ? 1 : 0; + *p++ = lk->is_server; uint8_t family = 0, addr_len = 0; uint8_t addr[16] = {0}; uint16_t port = 0; const struct sockaddr_storage* sa = &lk->remote_addr; if (sa->ss_family == AF_INET) { diff --git a/tools/chatgui-android/jni_bridge/android_jni_bridge.c b/tools/chatgui-android/jni_bridge/android_jni_bridge.c index f74fc0f7..4d80736e 100644 --- a/tools/chatgui-android/jni_bridge/android_jni_bridge.c +++ b/tools/chatgui-android/jni_bridge/android_jni_bridge.c @@ -812,14 +812,6 @@ char* utun_bridge_get_member_detail_json(const char* channel_id, uint64_t node_i } char peers_tbl[80]; peers_table_name(channel_id, peers_tbl, sizeof(peers_tbl)); - - { /* server/client role */ - struct ETCP_CONN* detail_conn = NULL; - if (g_cc.inst) detail_conn = instance_find_conn(g_cc.inst, node_id); - const char* sc = (detail_conn && detail_conn->links) - ? (detail_conn->links->is_server ? "S" : "C") : ""; - pos += (size_t)snprintf(buf + pos, sizeof(buf) - pos, ",\"sc\":\"%s\"", sc); - } snprintf(buf + pos, sizeof(buf) - pos, ",\"adr\":["); pos += strlen(buf + pos); if (sqlite3_prepare_v2(db, @@ -1038,8 +1030,8 @@ char* utun_bridge_get_member_links_json(uint64_t node_id) { if (!ip[0]) continue; const char* sep = first ? "" : ","; first = 0; pos += snprintf(buf + pos, sizeof(buf) - (size_t)pos, - "%s{\"fm\":%d,\"ad\":\"%s\",\"po\":%d,\"st\":%d,\"ls\":%d}", - sep, fm, ip, (int)po, lk->link_state, lk->link_status); + "%s{\"fm\":%d,\"ad\":\"%s\",\"po\":%d,\"st\":%d,\"ls\":%d,\"is\":%d}", + sep, fm, ip, (int)po, lk->link_state, lk->link_status, lk->is_server); } for (struct ETCP_LINK* lk2 = conn->links; lk2; lk2 = lk2->next) { if (!lk2->is_tcp || !lk2->tcp_link) continue; @@ -1062,8 +1054,8 @@ char* utun_bridge_get_member_links_json(uint64_t node_id) { int ready = stcp_link_is_ready(tcp); const char* sep = first ? "" : ","; first = 0; pos += snprintf(buf + pos, sizeof(buf) - (size_t)pos, - "%s{\"fm\":%d,\"ad\":\"%s\",\"po\":%d,\"st\":%d,\"ls\":%d}", - sep, fm, ip, (int)po, ready ? 3 : 1, ready ? 1 : 0); + "%s{\"fm\":%d,\"ad\":\"%s\",\"po\":%d,\"st\":%d,\"ls\":%d,\"is\":%d}", + sep, fm, ip, (int)po, ready ? 3 : 1, ready ? 1 : 0, lk2->is_server); } if (pos < (int)sizeof(buf)) pos += snprintf(buf + pos, sizeof(buf) - (size_t)pos, "]}"); diff --git a/tools/chatgui/src/accountlist.cpp b/tools/chatgui/src/accountlist.cpp index 98d30413..de604755 100644 --- a/tools/chatgui/src/accountlist.cpp +++ b/tools/chatgui/src/accountlist.cpp @@ -154,8 +154,6 @@ void AccountList::showMemberDetail(quint64 nodeId) { m_snapConnPresent = false; m_snapConnUp = false; m_snapConnInit = false; - m_snapClient = false; - m_snapServer = false; m_snapOwnTcpActive = 0; m_snapLinks.clear(); m_snapSocks.clear(); @@ -246,8 +244,6 @@ void AccountList::onMemberDetailData(uint64_t nodeId, const uint8_t* data, int l m_snapConnPresent = (flags & 1) != 0; m_snapConnUp = (flags & 2) != 0; m_snapConnInit = (flags & 4) != 0; - m_snapClient = (flags & 8) != 0; - m_snapServer = (flags & 16) != 0; uint16_t ownTcpActive; memcpy(&ownTcpActive, p, 2); p += 2; m_snapOwnTcpActive = ownTcpActive; @@ -261,10 +257,11 @@ void AccountList::onMemberDetailData(uint64_t nodeId, const uint8_t* data, int l lk.linkState = p[1]; lk.linkStatus = p[2]; lk.tcpReady = p[3] != 0; - lk.family = p[4]; - int addrLen = p[5]; - lk.addr = QByteArray((const char*)p + 6, qMin(addrLen, 16)); - memcpy(&lk.port, p + 22, 2); + lk.isServer = p[4] != 0; + lk.family = p[5]; + int addrLen = p[6]; + lk.addr = QByteArray((const char*)p + 7, qMin(addrLen, 16)); + memcpy(&lk.port, p + 23, 2); p += MEMBER_DETAIL_LINK_SIZE; m_snapLinks.append(lk); } @@ -306,11 +303,8 @@ void AccountList::updateDetailDisplay() { lines.append(QString("ID:0x%1").arg(m_detailNodeId, 16, 16, QChar('0'))); QString dotColor = m_detailOnline ? "#4CAF50" : "#9E9E9E"; - QString scLabel; - if (m_snapClient) scLabel = " C"; - else if (m_snapServer) scLabel = " S"; - lines.append(QString("● %2%3") - .arg(dotColor, m_detailName.toHtmlEscaped(), scLabel)); + lines.append(QString("● %2") + .arg(dotColor, m_detailName.toHtmlEscaped())); if (m_detailLastSeen > 0) lines.append(QString("⌛ %1").arg(relativeTimeStr(m_detailLastSeen))); @@ -323,18 +317,19 @@ void AccountList::updateDetailDisplay() { for (const auto& a : m_detailAddrs) { QString proto; switch (a.protocol) { case 1: proto = "UDP"; break; case 2: proto = "TCP"; break; default: proto = "UDP/TCP"; break; } - QString linkColor = "#9E9E9E"; + QString linkColor = "#9E9E9E"; QString scRole; if (m_snapConnPresent) { for (const auto& lk : m_snapLinks) { if (lk.family == a.family && lk.port == a.port && lk.addr == a.addr) { linkColor = (lk.linkState == 3 && lk.linkStatus == 1) ? "#4CAF50" : "#E53935"; + scRole = lk.isServer ? " S" : " C"; break; } } if (linkColor == "#9E9E9E" && a.protocol == 2) { for (const auto& lk : m_snapLinks) { - if (lk.isTcp && lk.tcpReady) { linkColor = "#4CAF50"; break; } + if (lk.isTcp && lk.tcpReady) { linkColor = "#4CAF50"; scRole = lk.isServer ? " S" : " C"; break; } } } } @@ -353,13 +348,13 @@ void AccountList::updateDetailDisplay() { } if (!a.ifname.isEmpty()) { - lines.append(QString("%1● %3 %4") - .arg(prefix, linkColor, proto, a.ifname)); + lines.append(QString("%1● %3%4 %5") + .arg(prefix, linkColor, proto, scRole, a.ifname)); lines.append(QString("  %1:%2") .arg(addrStr(a.addr.constData(), a.family)).arg(a.port)); } else { - lines.append(QString("%1● %3:%4:%5") - .arg(prefix, linkColor, proto, addrStr(a.addr.constData(), a.family)).arg(a.port)); + lines.append(QString("%1● %3%4:%5:%6") + .arg(prefix, linkColor, proto, scRole, addrStr(a.addr.constData(), a.family)).arg(a.port)); } } @@ -374,9 +369,10 @@ void AccountList::updateDetailDisplay() { } if (matched) continue; QString proto = lk.isTcp ? "TCP" : "UDP"; + QString sc = lk.isServer ? " S" : " C"; QString lc = (lk.linkState == 3 && lk.linkStatus == 1) ? "#4CAF50" : "#E53935"; - lines.append(QString("● %2:%3:%4 [link]") - .arg(lc, proto, addrStr(lk.addr.constData(), lk.family)).arg(lk.port)); + lines.append(QString("● %2%3:%4:%5 [link]") + .arg(lc, proto, sc, addrStr(lk.addr.constData(), lk.family)).arg(lk.port)); } } diff --git a/tools/chatgui/src/accountlist.h b/tools/chatgui/src/accountlist.h index 09ec88fc..302a7fce 100644 --- a/tools/chatgui/src/accountlist.h +++ b/tools/chatgui/src/accountlist.h @@ -26,6 +26,7 @@ struct MemberLinkSnap { int linkState; int linkStatus; bool tcpReady; + bool isServer; int family; QByteArray addr; uint16_t port; @@ -89,8 +90,6 @@ private: bool m_snapConnPresent = false; bool m_snapConnUp = false; bool m_snapConnInit = false; - bool m_snapClient = false; - bool m_snapServer = false; int m_snapOwnTcpActive = 0; QVector m_snapLinks; QVector m_snapSocks; diff --git a/tools/chatgui/transport/gui_bridge.h b/tools/chatgui/transport/gui_bridge.h index 6f8cb65f..8aaf45c4 100644 --- a/tools/chatgui/transport/gui_bridge.h +++ b/tools/chatgui/transport/gui_bridge.h @@ -36,7 +36,7 @@ struct TOPO_GROUP_NODE; #define GUI_EVT_MEMBER_REMOVED 25 /* data: [ch_id_len:1][ch_id:var][node_id:8] — мембер удалён из канала */ /* Размеры элементов пакета GUI_EVT_MEMBER_DETAIL (должны совпадать с chat_status.c) */ -#define MEMBER_DETAIL_LINK_SIZE 24 +#define MEMBER_DETAIL_LINK_SIZE 25 #define MEMBER_DETAIL_SOCK_SIZE 48 #define MEMBER_DETAIL_MAX_LINKS 16 #define MEMBER_DETAIL_MAX_SOCKS 16