@ -22,7 +22,8 @@
# define WINDOW_WIDTH 1000
# define WINDOW_WIDTH 1000
# define WINDOW_HEIGHT 1400
# define WINDOW_HEIGHT 1400
# define WINDOW_CLIENT_W 1250
# define WINDOW_CLIENT_W 1250
# define UPDATE_INTERVAL 10 /* 50ms → 20 samples per second */
# define UPDATE_INTERVAL 10
# define LIST_UPDATE_INTERVAL 1000
/* Global app pointer for callbacks */
/* Global app pointer for callbacks */
static struct etcpmon_app * g_app = NULL ;
static struct etcpmon_app * g_app = NULL ;
/* Forward declarations */
/* Forward declarations */
@ -1121,8 +1122,8 @@ static void OnConnect(struct etcpmon_app* app) {
if ( etcpmon_client_connect ( app - > client , addr , port ) = = 0 ) {
if ( etcpmon_client_connect ( app - > client , addr , port ) = = 0 ) {
app - > isConnected = 1 ;
app - > isConnected = 1 ;
app - > need_initial_request = 1 ;
UpdateUIState ( app ) ;
UpdateUIState ( app ) ;
etcpmon_gui_set_status ( app , " Connected " ) ;
} else {
} else {
etcpmon_gui_set_status ( app , " Connection failed " ) ;
etcpmon_gui_set_status ( app , " Connection failed " ) ;
}
}
@ -1131,11 +1132,7 @@ static void OnDisconnect(struct etcpmon_app* app) {
if ( ! app | | ! app - > client ) return ;
if ( ! app | | ! app - > client ) return ;
etcpmon_client_disconnect ( app - > client ) ;
etcpmon_client_disconnect ( app - > client ) ;
app - > isConnected = 0 ;
on_disconnected ( app ) ;
app - > need_initial_request = 1 ;
app - > last_selected_peer_id = 0 ;
UpdateUIState ( app ) ;
etcpmon_gui_set_status ( app , " Disconnected " ) ;
}
}
static void OnConnectionSelect ( struct etcpmon_app * app ) {
static void OnConnectionSelect ( struct etcpmon_app * app ) {
@ -1144,14 +1141,19 @@ static void OnConnectionSelect(struct etcpmon_app* app) {
int idx = ( int ) SendMessage ( app - > hListConnections , LB_GETCURSEL , 0 , 0 ) ;
int idx = ( int ) SendMessage ( app - > hListConnections , LB_GETCURSEL , 0 , 0 ) ;
if ( idx = = LB_ERR ) return ;
if ( idx = = LB_ERR ) return ;
uint64_t peer_id = ( uint64_t ) SendMessage ( app - > hListConnections , LB_GETITEMDATA , idx , 0 ) ;
LRESULT list_idx = SendMessage ( app - > hListConnections , LB_GETITEMDATA , idx , 0 ) ;
if ( list_idx < 0 | | list_idx > = app - > client - > conn_count ) return ;
uint64_t peer_id = app - > client - > conn_list [ list_idx ] . peer_node_id ;
if ( peer_id = = 0 ) return ;
if ( peer_id = = 0 ) return ;
/* Только если действительно изменилось — иначе спамим сервер */
/* Только если действительно изменилось — иначе спамим сервер */
if ( peer_id ! = app - > last_selected_peer_id ) {
if ( peer_id ! = app - > last_selected_peer_id ) {
if ( etcpmon_client_select_connection ( app - > client , peer_id ) ! = 0 ) {
OnDisconnect ( app ) ;
etcpmon_gui_set_status ( app , " Failed to select connection " ) ;
return ;
}
app - > last_selected_peer_id = peer_id ;
app - > last_selected_peer_id = peer_id ;
etcpmon_client_select_connection ( app - > client , peer_id ) ;
etcpmon_gui_clear_metrics ( app ) ; /* очищаем старые цифры */
etcpmon_gui_clear_metrics ( app ) ; /* очищаем старые цифры */
etcpmon_gui_set_status ( app , " Connection selected " ) ;
etcpmon_gui_set_status ( app , " Connection selected " ) ;
@ -1264,9 +1266,7 @@ static void RefreshDebugUI(struct etcpmon_app* app) {
static void OnTimer ( struct etcpmon_app * app ) {
static void OnTimer ( struct etcpmon_app * app ) {
if ( ! app | | ! app - > client ) return ;
if ( ! app | | ! app - > client ) return ;
if ( ! app - > client - > connected ) return ;
// fprintf(app->client->log_file, "Timer... \n");
// fflush(app->client->log_file);
int processed = etcpmon_client_process ( app - > client ) ;
int processed = etcpmon_client_process ( app - > client ) ;
if ( processed < 0 ) {
if ( processed < 0 ) {
@ -1274,10 +1274,17 @@ static void OnTimer(struct etcpmon_app* app) {
return ;
return ;
}
}
if ( app - > need_initial_request & & app - > isConnected ) {
if ( ! app - > client - > fully_connected ) return ;
etcpmon_client_request_list ( app - > client ) ;
etcpmon_client_request_socket_list ( app - > client ) ;
DWORD now = GetTickCount ( ) ;
etcpmon_client_request_debug_config ( app - > client ) ;
if ( app - > need_initial_request | | now - app - > last_poll_time > = LIST_UPDATE_INTERVAL ) {
if ( etcpmon_client_request_list ( app - > client ) ! = 0 | | etcpmon_client_request_socket_list ( app - > client ) ! = 0 | |
( app - > need_initial_request & & etcpmon_client_request_debug_config ( app - > client ) ! = 0 ) ) {
OnDisconnect ( app ) ;
etcpmon_gui_set_status ( app , " Failed to request monitor data " ) ;
return ;
}
app - > last_poll_time = now ;
app - > need_initial_request = 0 ;
app - > need_initial_request = 0 ;
}
}
@ -1324,6 +1331,12 @@ void etcpmon_gui_update_graph(struct etcpmon_app* app, struct etcpmon_rsp_metric
static void on_disconnected ( void * user_data ) {
static void on_disconnected ( void * user_data ) {
struct etcpmon_app * app = ( struct etcpmon_app * ) user_data ;
struct etcpmon_app * app = ( struct etcpmon_app * ) user_data ;
app - > isConnected = 0 ;
app - > isConnected = 0 ;
app - > need_initial_request = 1 ;
app - > last_selected_peer_id = 0 ;
app - > last_poll_time = 0 ;
SendMessage ( app - > hListConnections , LB_RESETCONTENT , 0 , 0 ) ;
SendMessage ( app - > hListSockets , LB_RESETCONTENT , 0 , 0 ) ;
etcpmon_gui_clear_metrics ( app ) ;
UpdateUIState ( app ) ;
UpdateUIState ( app ) ;
etcpmon_gui_set_status ( app , " Disconnected " ) ;
etcpmon_gui_set_status ( app , " Disconnected " ) ;
}
}
@ -1333,17 +1346,16 @@ static void on_conn_list(struct etcpmon_conn_info* list, uint8_t count, void* us
etcpmon_gui_update_conn_list ( app , list , count ) ;
etcpmon_gui_update_conn_list ( app , list , count ) ;
/* Автоматически выбираем первое соединение (только один раз) */
if ( count > 0 ) {
if ( count > 0 & & app - > last_selected_peer_id = = 0 ) {
OnConnectionSelect ( app ) ;
uint64_t first_id = list [ 0 ] . peer_node_id ;
} else if ( app - > last_selected_peer_id ! = 0 ) {
app - > last_selected_peer_id = first_id ;
if ( etcpmon_client_select_connection ( app - > client , 0 ) ! = 0 ) {
OnDisconnect ( app ) ;
etcpmon_client_select_connection ( app - > client , first_id ) ;
return ;
}
/* Выделяем первую строку в списке */
app - > last_selected_peer_id = 0 ;
SendMessage ( app - > hListConnections , LB_SETCURSEL , 0 , 0 ) ;
etcpmon_gui_clear_metrics ( app ) ;
etcpmon_gui_set_status ( app , " No connections " ) ;
etcpmon_gui_set_status ( app , " Auto-selected first connection " ) ;
}
}
}
}
@ -1358,7 +1370,6 @@ static void on_metrics(struct etcpmon_rsp_metrics* metrics,
struct etcpmon_app * app = ( struct etcpmon_app * ) user_data ;
struct etcpmon_app * app = ( struct etcpmon_app * ) user_data ;
if ( app ) {
if ( app ) {
etcpmon_gui_update_metrics ( app , metrics , links , links_count ) ;
etcpmon_gui_update_metrics ( app , metrics , links , links_count ) ;
etcpmon_client_add_to_history ( app - > client , metrics ) ;
if ( ! app - > graph_cursor_active ) {
if ( ! app - > graph_cursor_active ) {
struct metrics_history * h = etcpmon_client_get_history ( app - > client ) ;
struct metrics_history * h = etcpmon_client_get_history ( app - > client ) ;
if ( h & & h - > count > 0 ) {
if ( h & & h - > count > 0 ) {
@ -1522,7 +1533,24 @@ void etcpmon_gui_update_conn_list(struct etcpmon_app* app,
uint8_t count ) {
uint8_t count ) {
if ( ! app | | ! app - > hListConnections ) return ;
if ( ! app | | ! app - > hListConnections ) return ;
/* Clear existing items */
int selected = count ? 0 : - 1 ;
int changed = SendMessage ( app - > hListConnections , LB_GETCOUNT , 0 , 0 ) ! = count ;
for ( uint8_t i = 0 ; i < count ; i + + ) {
if ( list [ i ] . peer_node_id = = app - > last_selected_peer_id ) selected = i ;
char display [ 64 ] , previous [ 64 ] ;
snprintf ( display , sizeof ( display ) , " %s (%016llX) " , list [ i ] . name , ( unsigned long long ) list [ i ] . peer_node_id ) ;
if ( ! changed & & ( SendMessage ( app - > hListConnections , LB_GETTEXTLEN , i , 0 ) > = ( LRESULT ) sizeof ( previous ) | |
SendMessageA ( app - > hListConnections , LB_GETTEXT , i , ( LPARAM ) previous ) = = LB_ERR | | strcmp ( display , previous ) ! = 0 ) ) {
changed = 1 ;
}
}
if ( ! changed ) {
SendMessage ( app - > hListConnections , LB_SETCURSEL , selected , 0 ) ;
return ;
}
int top = ( int ) SendMessage ( app - > hListConnections , LB_GETTOPINDEX , 0 , 0 ) ;
SendMessage ( app - > hListConnections , WM_SETREDRAW , FALSE , 0 ) ;
SendMessage ( app - > hListConnections , LB_RESETCONTENT , 0 , 0 ) ;
SendMessage ( app - > hListConnections , LB_RESETCONTENT , 0 , 0 ) ;
/* Add new items */
/* Add new items */
@ -1532,10 +1560,22 @@ void etcpmon_gui_update_conn_list(struct etcpmon_app* app,
list [ i ] . name , ( unsigned long long ) list [ i ] . peer_node_id ) ;
list [ i ] . name , ( unsigned long long ) list [ i ] . peer_node_id ) ;
int idx = ( int ) SendMessageA ( app - > hListConnections , LB_ADDSTRING , 0 , ( LPARAM ) display ) ;
int idx = ( int ) SendMessageA ( app - > hListConnections , LB_ADDSTRING , 0 , ( LPARAM ) display ) ;
if ( idx ! = LB_ERR ) {
if ( idx ! = LB_ERR & & idx ! = LB_ERRSPACE ) {
SendMessage ( app - > hListConnections , LB_SETITEMDATA , idx , ( LPARAM ) list [ i ] . peer_node_id ) ;
/* Индекс сохраняет полный 64-битный ID и в 32-битной Windows. */
SendMessage ( app - > hListConnections , LB_SETITEMDATA , idx , i ) ;
} else if ( app - > client & & app - > client - > log_file ) {
fprintf ( app - > client - > log_file , " [ERROR] Failed to add connection row: index=%u result=%d \n " , i , idx ) ;
}
}
}
}
SendMessage ( app - > hListConnections , LB_SETCURSEL , selected , 0 ) ;
if ( top > = 0 & & top < count ) SendMessage ( app - > hListConnections , LB_SETTOPINDEX , top , 0 ) ;
SendMessage ( app - > hListConnections , WM_SETREDRAW , TRUE , 0 ) ;
InvalidateRect ( app - > hListConnections , NULL , TRUE ) ;
if ( app - > client & & app - > client - > log_file ) {
fprintf ( app - > client - > log_file , " [LOG] Connections updated: count=%u selected_row=%d previous_peer=%016llX \n " ,
count , selected , ( unsigned long long ) app - > last_selected_peer_id ) ;
fflush ( app - > client - > log_file ) ;
}
}
}
static const char * config_type_to_string ( uint8_t config_type ) {
static const char * config_type_to_string ( uint8_t config_type ) {
@ -1565,7 +1605,7 @@ static const char* nat_type_to_string(uint8_t nat_type) {
void etcpmon_gui_update_socket_list ( struct etcpmon_app * app ,
void etcpmon_gui_update_socket_list ( struct etcpmon_app * app ,
struct etcpmon_socket_info * list ,
struct etcpmon_socket_info * list ,
uint8_t count ) {
uint8_t count ) {
if ( ! app | | ! app - > hListSockets | | ! list | | count = = 0 | | count > 32 ) return ;
if ( ! app | | ! app - > hListSockets ) return ;
SendMessage ( app - > hListSockets , LB_RESETCONTENT , 0 , 0 ) ;
SendMessage ( app - > hListSockets , LB_RESETCONTENT , 0 , 0 ) ;
@ -1917,4 +1957,15 @@ void etcpmon_gui_clear_metrics(struct etcpmon_app* app) {
if ( app - > hListLinks ) {
if ( app - > hListLinks ) {
SendMessage ( app - > hListLinks , LB_RESETCONTENT , 0 , 0 ) ;
SendMessage ( app - > hListLinks , LB_RESETCONTENT , 0 , 0 ) ;
}
}
if ( app - > client ) {
memset ( & app - > client - > history , 0 , sizeof ( app - > client - > history ) ) ;
free ( app - > client - > last_metrics ) ;
app - > client - > last_metrics = NULL ;
free ( app - > client - > last_links ) ;
app - > client - > last_links = NULL ;
app - > client - > last_links_count = 0 ;
}
app - > graph_cursor_active = 0 ;
for ( int i = 0 ; i < GRAPH_METRICS_COUNT ; i + + ) SetWindowTextA ( app - > hChannelValue [ i ] , " " ) ;
if ( app - > hGraphWnd ) InvalidateRect ( app - > hGraphWnd , NULL , TRUE ) ;
}
}