mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-10-30 05:46:46 +01:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			fix_log_on
			...
			netprof
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | fd263e3e0a | ||
|  | 15ab58aa13 | ||
|  | b91f5a8758 | 
| @@ -21,7 +21,6 @@ cc_binary( | |||||||
|         "-std=gnu99", |         "-std=gnu99", | ||||||
|         "-DAUDIO", |         "-DAUDIO", | ||||||
|         "-DGAMES", |         "-DGAMES", | ||||||
|         "-DHAVE_WIDECHAR", |  | ||||||
|         "-DPACKAGE_DATADIR='\"data\"'", |         "-DPACKAGE_DATADIR='\"data\"'", | ||||||
|         "-DPYTHON", |         "-DPYTHON", | ||||||
|         "-DQRCODE", |         "-DQRCODE", | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @@ -12,9 +12,9 @@ CFLAGS += ${USER_CFLAGS} | |||||||
| LDFLAGS ?= | LDFLAGS ?= | ||||||
| LDFLAGS += ${USER_LDFLAGS} | LDFLAGS += ${USER_LDFLAGS} | ||||||
|  |  | ||||||
| OBJ = autocomplete.o avatars.o bootstrap.o chat.o chat_commands.o conference.o configdir.o curl_util.o execute.o | OBJ = autocomplete.o avatars.o bootstrap.o chat.o chat_commands.o configdir.o curl_util.o execute.o | ||||||
| OBJ += file_transfers.o friendlist.o global_commands.o conference_commands.o groupchats.o groupchat_commands.o help.o | OBJ += file_transfers.o friendlist.o global_commands.o conference_commands.o conference.o help.o input.o line_info.o | ||||||
| OBJ += input.o line_info.o log.o message_queue.o misc_tools.o name_lookup.o notify.o prompt.o qr_code.o settings.o | OBJ += log.o message_queue.o misc_tools.o name_lookup.o netprof.o notify.o prompt.o qr_code.o settings.o | ||||||
| OBJ += term_mplex.o toxic.o toxic_strings.o windows.o | OBJ += term_mplex.o toxic.o toxic_strings.o windows.o | ||||||
|  |  | ||||||
| # Check if debug build is enabled | # Check if debug build is enabled | ||||||
|   | |||||||
| @@ -2,12 +2,12 @@ | |||||||
| .\"     Title: toxic.conf | .\"     Title: toxic.conf | ||||||
| .\"    Author: [see the "AUTHORS" section] | .\"    Author: [see the "AUTHORS" section] | ||||||
| .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> | .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> | ||||||
| .\"      Date: 2020-11-12 | .\"      Date: 2021-05-24 | ||||||
| .\"    Manual: Toxic Manual | .\"    Manual: Toxic Manual | ||||||
| .\"    Source: toxic __VERSION__ | .\"    Source: toxic __VERSION__ | ||||||
| .\"  Language: English | .\"  Language: English | ||||||
| .\" | .\" | ||||||
| .TH "TOXIC\&.CONF" "5" "2020\-11\-12" "toxic __VERSION__" "Toxic Manual" | .TH "TOXIC\&.CONF" "5" "2021\-05\-24" "toxic __VERSION__" "Toxic Manual" | ||||||
| .\" ----------------------------------------------------------------- | .\" ----------------------------------------------------------------- | ||||||
| .\" * Define some portability stuff | .\" * Define some portability stuff | ||||||
| .\" ----------------------------------------------------------------- | .\" ----------------------------------------------------------------- | ||||||
| @@ -138,9 +138,9 @@ Show welcome message on startup\&. true or false | |||||||
| Enable friend connection change notifications\&. true or false | Enable friend connection change notifications\&. true or false | ||||||
| .RE | .RE | ||||||
| .PP | .PP | ||||||
| \fBshow_group_connection_msg\fR | \fBshow_network_info\fR | ||||||
| .RS 4 | .RS 4 | ||||||
| Enable group connection change notifications (does not include quit messages)\&. true or false | Show network information in the UI home window\&. true or false | ||||||
| .RE | .RE | ||||||
| .PP | .PP | ||||||
| \fBnodelist_update_freq\fR | \fBnodelist_update_freq\fR | ||||||
| @@ -191,11 +191,6 @@ Set user status when attaching and detaching from GNU screen or tmux\&. true or | |||||||
| \fBmplex_away_note\fR | \fBmplex_away_note\fR | ||||||
| .RS 4 | .RS 4 | ||||||
| Status message to set when status is set to away due to screen/tmux detach\&. When attaching, the status message is set back to the original value\&. | Status message to set when status is set to away due to screen/tmux detach\&. When attaching, the status message is set back to the original value\&. | ||||||
| .RE |  | ||||||
| .PP |  | ||||||
| \fBgroup_part_message\fR |  | ||||||
| .RS 4 |  | ||||||
| Parting message that will be sent to all groupchat peers when you leave the group\&. |  | ||||||
| .sp | .sp | ||||||
| .if n \{\ | .if n \{\ | ||||||
| .RS 4 | .RS 4 | ||||||
|   | |||||||
| @@ -87,8 +87,8 @@ OPTIONS | |||||||
|     *show_connection_msg*;; |     *show_connection_msg*;; | ||||||
|         Enable friend connection change notifications. true or false |         Enable friend connection change notifications. true or false | ||||||
|  |  | ||||||
|     *show_group_connection_msg*;; |     *show_network_info*;; | ||||||
|         Enable group connection change notifications (does not include quit messages). true or false |         Show network information in the UI home window. true or false | ||||||
|  |  | ||||||
|     *nodelist_update_freq*;; |     *nodelist_update_freq*;; | ||||||
|         How often in days to update the DHT nodes list. (integer; 0 to disable) |         How often in days to update the DHT nodes list. (integer; 0 to disable) | ||||||
| @@ -124,9 +124,6 @@ OPTIONS | |||||||
|         detach. When attaching, the status message is set back to the original |         detach. When attaching, the status message is set back to the original | ||||||
|         value. |         value. | ||||||
|  |  | ||||||
|     *group_part_message*;; |  | ||||||
| 	Parting message that will be sent to all groupchat peers when you leave the group. |  | ||||||
|  |  | ||||||
|     The following options control whether to output a terminal bell on certain events. |     The following options control whether to output a terminal bell on certain events. | ||||||
|     Some terminals mark the window as urgent when a bell is received. Urgent windows are usually highlighted in the taskbar and some window managers even provide shortcuts to jump to the next urgent window. |     Some terminals mark the window as urgent when a bell is received. Urgent windows are usually highlighted in the taskbar and some window managers even provide shortcuts to jump to the next urgent window. | ||||||
|     These options don't affect the "alerts" option. |     These options don't affect the "alerts" option. | ||||||
|   | |||||||
| @@ -56,8 +56,8 @@ ui = { | |||||||
|   // true to show friend connection change messages on the home screen |   // true to show friend connection change messages on the home screen | ||||||
|   show_connection_msg=true; |   show_connection_msg=true; | ||||||
|  |  | ||||||
|   // true to show peer connection change messages in groups (setting to false does not include user quit messages) |   // true to show network information in the UI home window | ||||||
|   show_group_connection_msg=true; |   show_network_info=true; | ||||||
|  |  | ||||||
|   // How often in days to update the DHT nodes list. (0 to disable updates) |   // How often in days to update the DHT nodes list. (0 to disable updates) | ||||||
|   nodeslist_update_freq=7; |   nodeslist_update_freq=7; | ||||||
| @@ -83,17 +83,11 @@ ui = { | |||||||
|   // Indicator for normal messages. |   // Indicator for normal messages. | ||||||
|   line_normal="-"; |   line_normal="-"; | ||||||
|  |  | ||||||
|   // Indicator for special messages. |  | ||||||
|   line_special=">"; |  | ||||||
|  |  | ||||||
|   // true to change status based on screen/tmux attach/detach, false to disable |   // true to change status based on screen/tmux attach/detach, false to disable | ||||||
|   mplex_away=true; |   mplex_away=true; | ||||||
|  |  | ||||||
|   // Status message to use when status set to away due to screen/tmux detach |   // Status message to use when status set to away due to screen/tmux detach | ||||||
|   mplex_away_note="Away from keyboard, be back soon!" |   mplex_away_note="Away from keyboard, be back soon!" | ||||||
|  |  | ||||||
|   // Parting message that will be sent to all groupchat peers when you leave the group |  | ||||||
|   group_part_message="Toxic user signing out" |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| audio = { | audio = { | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ | |||||||
| extern struct user_settings *user_settings; | extern struct user_settings *user_settings; | ||||||
|  |  | ||||||
| /* URL that we get the JSON encoded nodes list from. */ | /* URL that we get the JSON encoded nodes list from. */ | ||||||
| #define NODES_LIST_URL 0  // This should be empty until NGC merges with mainnet | #define NODES_LIST_URL "https://nodes.tox.chat/json" | ||||||
|  |  | ||||||
| #define DEFAULT_NODES_FILENAME "DHTnodes.json" | #define DEFAULT_NODES_FILENAME "DHTnodes.json" | ||||||
|  |  | ||||||
| @@ -79,28 +79,6 @@ extern struct user_settings *user_settings; | |||||||
| /* Maximum allowable size of the nodes list */ | /* Maximum allowable size of the nodes list */ | ||||||
| #define MAX_NODELIST_SIZE (MAX_RECV_CURL_DATA_SIZE) | #define MAX_NODELIST_SIZE (MAX_RECV_CURL_DATA_SIZE) | ||||||
|  |  | ||||||
| // TODO(Jfreegman): Remove this before production |  | ||||||
| static uint8_t const TESTNET_KEY[] = { |  | ||||||
|     0x79, 0xCA, 0xDA, 0x49, 0x74, 0xB0, 0x92, 0x6F, |  | ||||||
|     0x28, 0x6F, 0x02, 0x5C, 0xD5, 0xFF, 0xDF, 0x3E, |  | ||||||
|     0x65, 0x4A, 0x37, 0x58, 0xC5, 0x3E, 0x02, 0x73, |  | ||||||
|     0xEC, 0xFC, 0x4D, 0x12, 0xC2, 0x1D, 0xCA, 0x48, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // TODO(Jfreegman): Remove this before production |  | ||||||
| #define TESTNET_PORT 33445 |  | ||||||
|  |  | ||||||
| #define TESTNET_IP "172.93.52.70" |  | ||||||
|  |  | ||||||
| static uint8_t const TESTNET_KEY2[] = { |  | ||||||
|     0x5E, 0x47, 0xBA, 0x1D, 0xC3, 0x91, 0x3E, 0xB2, |  | ||||||
|     0xCB, 0xF2, 0xD6, 0x4C, 0xE4, 0xF2, 0x3D, 0x8B, |  | ||||||
|     0xFE, 0x53, 0x91, 0xBF, 0xAB, 0xE5, 0xC4, 0x3C, |  | ||||||
|     0x5B, 0xAD, 0x13, 0xF0, 0xA4, 0x14, 0xCD, 0x77, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #define TESTNET_PORT2 38445 |  | ||||||
| #define TESTNET_IP2 "tox.plastiras.org" |  | ||||||
|  |  | ||||||
| static struct Thread_Data { | static struct Thread_Data { | ||||||
|     pthread_t tid; |     pthread_t tid; | ||||||
| @@ -298,11 +276,6 @@ on_exit: | |||||||
|  */ |  */ | ||||||
| static int update_DHT_nodeslist(const char *nodes_path) | static int update_DHT_nodeslist(const char *nodes_path) | ||||||
| { | { | ||||||
|     if (NODES_LIST_URL == 0) {  // TODO: Remove this when NGC merges with mainnet |  | ||||||
|         fprintf(stderr, "Skipping DHT Nodes list fetching (remove before production)\n"); |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (!nodeslist_needs_update(nodes_path)) { |     if (!nodeslist_needs_update(nodes_path)) { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| @@ -583,24 +556,6 @@ on_exit: | |||||||
|  */ |  */ | ||||||
| int load_DHT_nodeslist(void) | int load_DHT_nodeslist(void) | ||||||
| { | { | ||||||
|     // TODO(Jfreegman): Remove this before production |  | ||||||
|     fprintf(stderr, "Adding NGC testnet node - remove this before production\n"); |  | ||||||
|  |  | ||||||
|     struct Node *node = &Nodes.list[0]; |  | ||||||
|     node->have_ip4 = true; |  | ||||||
|     node->port = TESTNET_PORT; |  | ||||||
|     memcpy(node->key, TESTNET_KEY, sizeof(TESTNET_KEY)); |  | ||||||
|     memcpy(node->ip4, TESTNET_IP, sizeof(TESTNET_IP)); |  | ||||||
|  |  | ||||||
|     struct Node *node2 = &Nodes.list[1]; |  | ||||||
|     node2->have_ip4 = true; |  | ||||||
|     node2->port = TESTNET_PORT2; |  | ||||||
|     memcpy(node2->key, TESTNET_KEY2, sizeof(TESTNET_KEY2)); |  | ||||||
|     memcpy(node2->ip4, TESTNET_IP2, sizeof(TESTNET_IP2)); |  | ||||||
|  |  | ||||||
|     Nodes.count = 2; |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
|     if (thread_data.active) { |     if (thread_data.active) { | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| @@ -623,7 +578,6 @@ int load_DHT_nodeslist(void) | |||||||
|         thread_data.active = false; |         thread_data.active = false; | ||||||
|         return -5; |         return -5; | ||||||
|     } |     } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										47
									
								
								src/chat.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								src/chat.c
									
									
									
									
									
								
							| @@ -69,15 +69,11 @@ static const char *chat_cmd_list[] = { | |||||||
|     "/add", |     "/add", | ||||||
|     "/avatar", |     "/avatar", | ||||||
|     "/cancel", |     "/cancel", | ||||||
|     "/cinvite", |  | ||||||
|     "/cjoin", |  | ||||||
|     "/clear", |     "/clear", | ||||||
|     "/close", |     "/close", | ||||||
|     "/connect", |     "/connect", | ||||||
|     "/exit", |     "/exit", | ||||||
|     "/gaccept", |  | ||||||
|     "/conference", |     "/conference", | ||||||
|     "/group", |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     "/game", |     "/game", | ||||||
|     "/play", |     "/play", | ||||||
| @@ -761,46 +757,8 @@ static void chat_onConferenceInvite(ToxWindow *self, Tox *m, int32_t friendnumbe | |||||||
|                    "invites you to join %s", description); |                    "invites you to join %s", description); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a conference.", name); |     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to %s.", name, description); | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Type \"/cjoin\" to join the chat."); |     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat."); | ||||||
| } |  | ||||||
|  |  | ||||||
| static void chat_onGroupInvite(ToxWindow *self, Tox *m, uint32_t friendnumber, const char *invite_data, size_t length, |  | ||||||
|                                const char *group_name, size_t group_name_length) |  | ||||||
| { |  | ||||||
|     UNUSED_VAR(group_name_length); |  | ||||||
|  |  | ||||||
|     if (self->num != friendnumber) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (Friends.list[friendnumber].group_invite.data) { |  | ||||||
|         free(Friends.list[friendnumber].group_invite.data); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Friends.list[friendnumber].group_invite.data = malloc(length * sizeof(uint8_t)); |  | ||||||
|  |  | ||||||
|     if (Friends.list[friendnumber].group_invite.data == NULL) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     memcpy(Friends.list[friendnumber].group_invite.data, invite_data, length); |  | ||||||
|     Friends.list[friendnumber].group_invite.length = length; |  | ||||||
|  |  | ||||||
|     sound_notify(self, generic_message, NT_WNDALERT_2 | user_settings->bell_on_invite, NULL); |  | ||||||
|  |  | ||||||
|     char name[TOX_MAX_NAME_LENGTH]; |  | ||||||
|     get_nick_truncate(m, name, friendnumber); |  | ||||||
|  |  | ||||||
|     if (self->active_box != -1) { |  | ||||||
|         box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, "invites you to join group chat"); |  | ||||||
|     } else { |  | ||||||
|         box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join group chat"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to join group chat \"%s\"", name, group_name); |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, |  | ||||||
|                   "Type \"/gaccept <password>\" to join the chat (password is optional)."); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
| @@ -1623,7 +1581,6 @@ ToxWindow *new_chat(Tox *m, uint32_t friendnum) | |||||||
|     ret->onFileControl = &chat_onFileControl; |     ret->onFileControl = &chat_onFileControl; | ||||||
|     ret->onFileRecv = &chat_onFileRecv; |     ret->onFileRecv = &chat_onFileRecv; | ||||||
|     ret->onReadReceipt = &chat_onReadReceipt; |     ret->onReadReceipt = &chat_onReadReceipt; | ||||||
|     ret->onGroupInvite = &chat_onGroupInvite; |  | ||||||
|  |  | ||||||
| #ifdef AUDIO | #ifdef AUDIO | ||||||
|     ret->onInvite = &chat_onInvite; |     ret->onInvite = &chat_onInvite; | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ | |||||||
| #include "file_transfers.h" | #include "file_transfers.h" | ||||||
| #include "friendlist.h" | #include "friendlist.h" | ||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "groupchats.h" |  | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| #include "toxic.h" | #include "toxic.h" | ||||||
| #include "windows.h" | #include "windows.h" | ||||||
| @@ -179,77 +178,6 @@ void cmd_conference_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| void cmd_group_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (get_num_active_windows() >= MAX_WINDOWS_NUM) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (Friends.list[self->num].group_invite.length == 0) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending group invite"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *passwd = NULL; |  | ||||||
|     uint16_t passwd_len = 0; |  | ||||||
|  |  | ||||||
|     if (argc > 0) { |  | ||||||
|         passwd = argv[1]; |  | ||||||
|         passwd_len = strlen(passwd); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     size_t nick_len = tox_self_get_name_size(m); |  | ||||||
|     char self_nick[TOX_MAX_NAME_LENGTH + 1]; |  | ||||||
|     tox_self_get_name(m, (uint8_t *) self_nick); |  | ||||||
|     self_nick[nick_len] = '\0'; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Invite_Accept err; |  | ||||||
|     uint32_t groupnumber = tox_group_invite_accept(m, self->num, Friends.list[self->num].group_invite.data, |  | ||||||
|                            Friends.list[self->num].group_invite.length, (const uint8_t *) self_nick, nick_len, |  | ||||||
|                            (const uint8_t *) passwd, passwd_len, &err); |  | ||||||
|  |  | ||||||
|     if (err != TOX_ERR_GROUP_INVITE_ACCEPT_OK) { |  | ||||||
|         if (err == TOX_ERR_GROUP_INVITE_ACCEPT_TOO_LONG) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group: Password too long."); |  | ||||||
|         } else { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group (error %d).", err); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (init_groupchat_win(m, groupnumber, NULL, 0, Group_Join_Type_Join) == -1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); |  | ||||||
|         tox_group_leave(m, groupnumber, NULL, 0, NULL); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_group_invite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group number required."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     int groupnumber = atoi(argv[1]); |  | ||||||
|  |  | ||||||
|     if (groupnumber == 0 && strcmp(argv[1], "0")) {    /* atoi returns 0 value on invalid input */ |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid group number."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Invite_Friend err; |  | ||||||
|  |  | ||||||
|     if (!tox_group_invite_friend(m, groupnumber, self->num, &err)) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group (error %d).", err); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnumber); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|  |  | ||||||
| void cmd_game_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) | void cmd_game_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) | ||||||
|   | |||||||
| @@ -29,8 +29,6 @@ | |||||||
| void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_conference_invite(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_conference_invite(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_conference_join(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_conference_join(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_group_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_group_invite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_game_join(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_game_join(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_savefile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_savefile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
|   | |||||||
| @@ -85,13 +85,11 @@ static const char *conference_cmd_list[] = { | |||||||
|     "/connect", |     "/connect", | ||||||
|     "/decline", |     "/decline", | ||||||
|     "/exit", |     "/exit", | ||||||
|     "/group", |  | ||||||
|     "/conference", |     "/conference", | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     "/game", |     "/game", | ||||||
| #endif | #endif | ||||||
|     "/help", |     "/help", | ||||||
|     "/join", |  | ||||||
|     "/log", |     "/log", | ||||||
| #ifdef AUDIO | #ifdef AUDIO | ||||||
|     "/mute", |     "/mute", | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| /*  conference_commands.h | /*  conference_commands.h | ||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  *  Copyright (C) 2020 Toxic All Rights Reserved. |  *  Copyright (C) 2014 Toxic All Rights Reserved. | ||||||
|  * |  * | ||||||
|  *  This file is part of Toxic. |  *  This file is part of Toxic. | ||||||
|  * |  * | ||||||
| @@ -33,4 +33,3 @@ void cmd_conference_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, cha | |||||||
| void cmd_conference_push_to_talk(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_conference_push_to_talk(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
|  |  | ||||||
| #endif /* CONFERENCE_COMMANDS_H */ | #endif /* CONFERENCE_COMMANDS_H */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ | |||||||
| #include "execute.h" | #include "execute.h" | ||||||
| #include "global_commands.h" | #include "global_commands.h" | ||||||
| #include "conference_commands.h" | #include "conference_commands.h" | ||||||
| #include "groupchat_commands.h" |  | ||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| #include "notify.h" | #include "notify.h" | ||||||
| @@ -50,12 +49,10 @@ static struct cmd_func global_commands[] = { | |||||||
|     { "/decline",   cmd_decline       }, |     { "/decline",   cmd_decline       }, | ||||||
|     { "/exit",      cmd_quit          }, |     { "/exit",      cmd_quit          }, | ||||||
|     { "/conference", cmd_conference    }, |     { "/conference", cmd_conference    }, | ||||||
|     { "/group",     cmd_groupchat     }, |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     { "/game",      cmd_game          }, |     { "/game",      cmd_game          }, | ||||||
| #endif | #endif | ||||||
|     { "/help",      cmd_prompt_help   }, |     { "/help",      cmd_prompt_help   }, | ||||||
|     { "/join",      cmd_join          }, |  | ||||||
|     { "/log",       cmd_log           }, |     { "/log",       cmd_log           }, | ||||||
|     { "/myid",      cmd_myid          }, |     { "/myid",      cmd_myid          }, | ||||||
| #ifdef QRCODE | #ifdef QRCODE | ||||||
| @@ -84,10 +81,8 @@ static struct cmd_func global_commands[] = { | |||||||
|  |  | ||||||
| static struct cmd_func chat_commands[] = { | static struct cmd_func chat_commands[] = { | ||||||
|     { "/cancel",    cmd_cancelfile        }, |     { "/cancel",    cmd_cancelfile        }, | ||||||
|     { "/cinvite",   cmd_conference_invite }, |     { "/invite",    cmd_conference_invite }, | ||||||
|     { "/cjoin",     cmd_conference_join   }, |     { "/join",      cmd_conference_join   }, | ||||||
|     { "/gaccept",   cmd_group_accept      }, |  | ||||||
|     { "/invite",    cmd_group_invite      }, |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     { "/play",      cmd_game_join         }, |     { "/play",      cmd_game_join         }, | ||||||
| #endif | #endif | ||||||
| @@ -122,50 +117,12 @@ static struct cmd_func conference_commands[] = { | |||||||
|     { NULL,         NULL             }, |     { NULL,         NULL             }, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static struct cmd_func groupchat_commands[] = { |  | ||||||
|     { "/chatid",    cmd_chatid         }, |  | ||||||
|     { "/disconnect", cmd_disconnect     }, |  | ||||||
|     { "/ignore",    cmd_ignore         }, |  | ||||||
|     { "/kick",      cmd_kick           }, |  | ||||||
|     { "/list",      cmd_list           }, |  | ||||||
|     { "/locktopic", cmd_set_topic_lock }, |  | ||||||
|     { "/mod",       cmd_mod            }, |  | ||||||
|     { "/passwd",    cmd_set_passwd     }, |  | ||||||
|     { "/peerlimit", cmd_set_peerlimit  }, |  | ||||||
|     { "/privacy",   cmd_set_privacy    }, |  | ||||||
|     { "/rejoin",    cmd_rejoin         }, |  | ||||||
|     { "/silence",   cmd_silence        }, |  | ||||||
|     { "/topic",     cmd_set_topic      }, |  | ||||||
|     { "/unignore",  cmd_unignore       }, |  | ||||||
|     { "/unmod",     cmd_unmod          }, |  | ||||||
|     { "/unsilence", cmd_unsilence      }, |  | ||||||
|     { "/voice",     cmd_set_voice      }, |  | ||||||
|     { "/whois",     cmd_whois          }, |  | ||||||
| #ifdef AUDIO |  | ||||||
|     { "/mute",      cmd_mute           }, |  | ||||||
|     { "/sense",     cmd_sense          }, |  | ||||||
| #endif /* AUDIO */ |  | ||||||
|     { NULL,         NULL               }, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* Special commands are commands that only take one argument even if it contains spaces */ | /* Special commands are commands that only take one argument even if it contains spaces */ | ||||||
| static const char special_commands[][MAX_CMDNAME_SIZE] = { | static const char special_commands[][MAX_CMDNAME_SIZE] = { | ||||||
|     "/add", |     "/add", | ||||||
|     "/avatar", |     "/avatar", | ||||||
|     "/gaccept", |  | ||||||
|     "/group", |  | ||||||
|     "/ignore", |  | ||||||
|     "/kick", |  | ||||||
|     "/mod", |  | ||||||
|     "/nick", |     "/nick", | ||||||
|     "/note", |     "/note", | ||||||
|     "/passwd", |  | ||||||
|     "/silence", |  | ||||||
|     "/topic", |  | ||||||
|     "/unignore", |  | ||||||
|     "/unmod", |  | ||||||
|     "/unsilence", |  | ||||||
|     "/whois", |  | ||||||
| #ifdef PYTHON | #ifdef PYTHON | ||||||
|     "/run", |     "/run", | ||||||
| #endif /* PYTHON */ | #endif /* PYTHON */ | ||||||
| @@ -286,29 +243,19 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode) | |||||||
|      * Note: Global commands must come last in case of duplicate command names |      * Note: Global commands must come last in case of duplicate command names | ||||||
|      */ |      */ | ||||||
|     switch (mode) { |     switch (mode) { | ||||||
|         case CHAT_COMMAND_MODE: { |         case CHAT_COMMAND_MODE: | ||||||
|             if (do_command(w, self, m, num_args, chat_commands, args) == 0) { |             if (do_command(w, self, m, num_args, chat_commands, args) == 0) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             break; |             break; | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case CONFERENCE_COMMAND_MODE: { |         case CONFERENCE_COMMAND_MODE: | ||||||
|             if (do_command(w, self, m, num_args, conference_commands, args) == 0) { |             if (do_command(w, self, m, num_args, conference_commands, args) == 0) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             break; |             break; | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case GROUPCHAT_COMMAND_MODE: { |  | ||||||
|             if (do_command(w, self, m, num_args, groupchat_commands, args) == 0) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (do_command(w, self, m, num_args, global_commands, args) == 0) { |     if (do_command(w, self, m, num_args, global_commands, args) == 0) { | ||||||
|   | |||||||
| @@ -32,7 +32,6 @@ enum { | |||||||
|     GLOBAL_COMMAND_MODE, |     GLOBAL_COMMAND_MODE, | ||||||
|     CHAT_COMMAND_MODE, |     CHAT_COMMAND_MODE, | ||||||
|     CONFERENCE_COMMAND_MODE, |     CONFERENCE_COMMAND_MODE, | ||||||
|     GROUPCHAT_COMMAND_MODE, |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode); | void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode); | ||||||
|   | |||||||
| @@ -116,10 +116,6 @@ void kill_friendlist(ToxWindow *self) | |||||||
|             free(Friends.list[i].game_invite.data); |             free(Friends.list[i].game_invite.data); | ||||||
| #endif | #endif | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (Friends.list[i].group_invite.data != NULL) { |  | ||||||
|             free(Friends.list[i].group_invite.data); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     realloc_blocklist(0); |     realloc_blocklist(0); | ||||||
| @@ -678,35 +674,6 @@ static void friendlist_onConferenceInvite(ToxWindow *self, Tox *m, int32_t num, | |||||||
|     sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); |     sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, uint32_t num, const char *data, size_t length, |  | ||||||
|                                      const char *group_name, size_t group_name_length) |  | ||||||
| { |  | ||||||
|     UNUSED_VAR(self); |  | ||||||
|     UNUSED_VAR(data); |  | ||||||
|     UNUSED_VAR(length); |  | ||||||
|  |  | ||||||
|     if (num >= Friends.max_idx) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (Friends.list[num].chatwin != -1) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (get_num_active_windows() < MAX_WINDOWS_NUM) { |  | ||||||
|         Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num)); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     char nick[TOX_MAX_NAME_LENGTH]; |  | ||||||
|     get_nick_truncate(m, nick, num); |  | ||||||
|  |  | ||||||
|     line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, |  | ||||||
|                   "* Group chat invite from %s failed: too many windows are open.", nick); |  | ||||||
|  |  | ||||||
|     sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* move friendlist/blocklist cursor up and down */ | /* move friendlist/blocklist cursor up and down */ | ||||||
| static void select_friend(wint_t key, int *selected, int num) | static void select_friend(wint_t key, int *selected, int num) | ||||||
| { | { | ||||||
| @@ -1431,7 +1398,6 @@ ToxWindow *new_friendlist(void) | |||||||
|     ret->onStatusMessageChange = &friendlist_onStatusMessageChange; |     ret->onStatusMessageChange = &friendlist_onStatusMessageChange; | ||||||
|     ret->onFileRecv = &friendlist_onFileRecv; |     ret->onFileRecv = &friendlist_onFileRecv; | ||||||
|     ret->onConferenceInvite = &friendlist_onConferenceInvite; |     ret->onConferenceInvite = &friendlist_onConferenceInvite; | ||||||
|     ret->onGroupInvite = &friendlist_onGroupInvite; |  | ||||||
|  |  | ||||||
| #ifdef AUDIO | #ifdef AUDIO | ||||||
|     ret->onInvite = &friendlist_onAV; |     ret->onInvite = &friendlist_onAV; | ||||||
|   | |||||||
| @@ -46,11 +46,6 @@ struct ConferenceInvite { | |||||||
|     bool pending; |     bool pending; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct GroupInvite { |  | ||||||
|     uint8_t *data; |  | ||||||
|     uint16_t length; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|  |  | ||||||
| struct GameInvite { | struct GameInvite { | ||||||
| @@ -78,16 +73,14 @@ typedef struct { | |||||||
|     Tox_User_Status status; |     Tox_User_Status status; | ||||||
|  |  | ||||||
|     struct LastOnline last_online; |     struct LastOnline last_online; | ||||||
|  |     struct ConferenceInvite conference_invite; | ||||||
|  |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     struct GameInvite game_invite; |     struct GameInvite game_invite; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     struct ConferenceInvite conference_invite; |     FileTransfer file_receiver[MAX_FILES]; | ||||||
|     struct GroupInvite group_invite; |     FileTransfer file_sender[MAX_FILES]; | ||||||
|  |  | ||||||
|     struct FileTransfer file_receiver[MAX_FILES]; |  | ||||||
|     struct FileTransfer file_sender[MAX_FILES]; |  | ||||||
|     PendingFileTransfer file_send_queue[MAX_FILES]; |     PendingFileTransfer file_send_queue[MAX_FILES]; | ||||||
| } ToxicFriend; | } ToxicFriend; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ | |||||||
| #include "avatars.h" | #include "avatars.h" | ||||||
| #include "conference.h" | #include "conference.h" | ||||||
| #include "friendlist.h" | #include "friendlist.h" | ||||||
| #include "groupchats.h" |  | ||||||
| #include "help.h" | #include "help.h" | ||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "log.h" | #include "log.h" | ||||||
| @@ -460,146 +459,6 @@ void cmd_conference(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar | |||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Conference [%d] created.", conferencenum); |     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Conference [%d] created.", conferencenum); | ||||||
| } | } | ||||||
|  |  | ||||||
| void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (get_num_active_windows() >= MAX_WINDOWS_NUM) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group name required"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *tmp_name = argv[1]; |  | ||||||
|     int len = strlen(tmp_name); |  | ||||||
|  |  | ||||||
|     if (len == 0 || len > TOX_GROUP_MAX_GROUP_NAME_LENGTH) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid group name."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     char name[TOX_GROUP_MAX_GROUP_NAME_LENGTH]; |  | ||||||
|  |  | ||||||
|     snprintf(name, sizeof(name), "%s", argv[1]); |  | ||||||
|  |  | ||||||
|     size_t nick_length = tox_self_get_name_size(m); |  | ||||||
|     char self_nick[TOX_MAX_NAME_LENGTH + 1]; |  | ||||||
|     tox_self_get_name(m, (uint8_t *) self_nick); |  | ||||||
|     self_nick[nick_length] = '\0'; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_New err; |  | ||||||
|     uint32_t groupnumber = tox_group_new(m, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *) name, len, |  | ||||||
|                                          (const uint8_t *) self_nick, nick_length, &err); |  | ||||||
|  |  | ||||||
|     if (err != TOX_ERR_GROUP_NEW_OK) { |  | ||||||
|         switch (err) { |  | ||||||
|             case TOX_ERR_GROUP_NEW_TOO_LONG: { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group name length cannot exceed %d.", |  | ||||||
|                               TOX_GROUP_MAX_GROUP_NAME_LENGTH); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case TOX_ERR_GROUP_NEW_EMPTY: { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group name cannot be empty."); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             default: { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize (error %d).", err); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     int init = init_groupchat_win(m, groupnumber, name, len, Group_Join_Type_Create); |  | ||||||
|  |  | ||||||
|     if (init == -1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); |  | ||||||
|         tox_group_leave(m, groupnumber, NULL, 0, NULL); |  | ||||||
|     } else if (init == -2) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, |  | ||||||
|                       "You have been kicked from a group. Close the window and try again."); |  | ||||||
|         tox_group_leave(m, groupnumber, NULL, 0, NULL); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (get_num_active_windows() >= MAX_WINDOWS_NUM) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Chat ID is required."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *chat_id = argv[1]; |  | ||||||
|  |  | ||||||
|     if (strlen(chat_id) != TOX_GROUP_CHAT_ID_SIZE * 2) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     char id_bin[TOX_GROUP_CHAT_ID_SIZE] = {0}; |  | ||||||
|  |  | ||||||
|     size_t i; |  | ||||||
|     char xch[3]; |  | ||||||
|     uint32_t x; |  | ||||||
|  |  | ||||||
|     for (i = 0; i < TOX_GROUP_CHAT_ID_SIZE; ++i) { |  | ||||||
|         xch[0] = chat_id[2 * i]; |  | ||||||
|         xch[1] = chat_id[2 * i + 1]; |  | ||||||
|         xch[2] = '\0'; |  | ||||||
|  |  | ||||||
|         if (sscanf(xch, "%02x", &x) != 1) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         id_bin[i] = x; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *passwd = NULL; |  | ||||||
|     uint16_t passwd_len = 0; |  | ||||||
|  |  | ||||||
|     if (argc > 1) { |  | ||||||
|         passwd = argv[2]; |  | ||||||
|         passwd_len = strlen(passwd); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     size_t nick_length = tox_self_get_name_size(m); |  | ||||||
|     char self_nick[TOX_MAX_NAME_LENGTH + 1]; |  | ||||||
|     tox_self_get_name(m, (uint8_t *) self_nick); |  | ||||||
|     self_nick[nick_length] = '\0'; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Join err; |  | ||||||
|     uint32_t groupnumber = tox_group_join(m, (uint8_t *) id_bin, (const uint8_t *) self_nick, nick_length, |  | ||||||
|                                           (const uint8_t *) passwd, passwd_len, &err); |  | ||||||
|  |  | ||||||
|     if (err != TOX_ERR_GROUP_JOIN_OK) { |  | ||||||
|         if (err == TOX_ERR_GROUP_JOIN_TOO_LONG) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password length cannot exceed %d.", TOX_GROUP_MAX_PASSWORD_SIZE); |  | ||||||
|         } else { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group (error %d).", err); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     int init = init_groupchat_win(m, groupnumber, NULL, 0, Group_Join_Type_Join); |  | ||||||
|  |  | ||||||
|     if (init == -1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); |  | ||||||
|         tox_group_leave(m, groupnumber, NULL, 0, NULL); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) | void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) | ||||||
| { | { | ||||||
|     UNUSED_VAR(window); |     UNUSED_VAR(window); | ||||||
| @@ -777,7 +636,6 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA | |||||||
|  |  | ||||||
|     tox_self_set_name(m, (uint8_t *) nick, len, NULL); |     tox_self_set_name(m, (uint8_t *) nick, len, NULL); | ||||||
|     prompt_update_nick(prompt, nick); |     prompt_update_nick(prompt, nick); | ||||||
|     set_nick_all_groups(m, nick, len); |  | ||||||
|  |  | ||||||
|     store_data(m, DATA_FILE); |     store_data(m, DATA_FILE); | ||||||
| } | } | ||||||
| @@ -904,8 +762,6 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ | |||||||
|  |  | ||||||
|     tox_self_set_status(m, status); |     tox_self_set_status(m, status); | ||||||
|     prompt_update_status(prompt, status); |     prompt_update_status(prompt, status); | ||||||
|     set_status_all_groups(m, status); |  | ||||||
|  |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Your status has been changed to %s.", status_str); |     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Your status has been changed to %s.", status_str); | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,11 +30,9 @@ void cmd_accept(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZ | |||||||
| void cmd_add(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_add(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_clear(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_clear(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_conference(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_connect(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_connect(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_groupchat(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_conference(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); | ||||||
| #ifdef QRCODE | #ifdef QRCODE | ||||||
|   | |||||||
| @@ -1,912 +0,0 @@ | |||||||
| /*  groupchat_commands.c |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  *  Copyright (C) 2020 Toxic All Rights Reserved. |  | ||||||
|  * |  | ||||||
|  *  This file is part of Toxic. |  | ||||||
|  * |  | ||||||
|  *  Toxic is free software: you can redistribute it and/or modify |  | ||||||
|  *  it under the terms of the GNU General Public License as published by |  | ||||||
|  *  the Free Software Foundation, either version 3 of the License, or |  | ||||||
|  *  (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  Toxic is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #include <string.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
|  |  | ||||||
| #include "toxic.h" |  | ||||||
| #include "windows.h" |  | ||||||
| #include "line_info.h" |  | ||||||
| #include "misc_tools.h" |  | ||||||
| #include "log.h" |  | ||||||
| #include "groupchats.h" |  | ||||||
|  |  | ||||||
| extern GroupChat groupchats[MAX_GROUPCHAT_NUM]; |  | ||||||
|  |  | ||||||
| void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     char chatid[TOX_GROUP_CHAT_ID_SIZE * 2 + 1] = {0}; |  | ||||||
|     char chat_public_key[TOX_GROUP_CHAT_ID_SIZE]; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_State_Queries err; |  | ||||||
|  |  | ||||||
|     if (!tox_group_get_chat_id(m, self->num, (uint8_t *) chat_public_key, &err)) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve the Chat ID (error %d).", err); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < TOX_GROUP_CHAT_ID_SIZE; ++i) { |  | ||||||
|         char xx[3]; |  | ||||||
|         snprintf(xx, sizeof(xx), "%02X", chat_public_key[i] & 0xff); |  | ||||||
|         strcat(chatid, xx); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", chatid); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_disconnect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     Tox_Err_Group_Disconnect err; |  | ||||||
|     tox_group_disconnect(m, self->num, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_DISCONNECT_OK: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Disconnected from group. Type '/rejoin' to reconnect."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_DISCONNECT_ALREADY_DISCONNECTED: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Already disconnected. Type '/rejoin' to connect."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to disconnect from group. Error: %d", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|     uint32_t peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Set_Ignore err; |  | ||||||
|     tox_group_set_ignore(m, self->num, peer_id, true, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_SET_IGNORE_OK: { |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_SET_IGNORE_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot ignore yourself."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_SET_IGNORE_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to toggle ignore on %s (error %d).", nick, err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 1, BLUE, "-!- Ignoring %s", nick); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|  |  | ||||||
|     uint32_t target_peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Mod_Kick_Peer err; |  | ||||||
|     tox_group_mod_kick_peer(m, self->num, target_peer_id, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_MOD_KICK_PEER_OK: { |  | ||||||
|             char self_nick[TOX_MAX_NAME_LENGTH + 1]; |  | ||||||
|             get_group_self_nick_truncate(m, self_nick, self->num); |  | ||||||
|  |  | ||||||
|             line_info_add(self, true, NULL, NULL, SYS_MSG, 1, RED, "-!- %s has been kicked by %s", nick, self_nick); |  | ||||||
|             groupchat_onGroupPeerExit(self, m, self->num, target_peer_id, TOX_GROUP_EXIT_TYPE_KICK, nick, strlen(nick), NULL, 0); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "You do not have permission to kick %s.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_KICK_PEER_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "You cannot kick yourself."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to kick %s from the group (error %d).", nick, |  | ||||||
|                           err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_list(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     GroupChat *chat = get_groupchat(self->num); |  | ||||||
|  |  | ||||||
|     if (!chat) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch GroupChat object."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < chat->max_idx; ++i) { |  | ||||||
|         GroupPeer *peer = &chat->peer_list[i]; |  | ||||||
|  |  | ||||||
|         if (!peer->active) { |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         char pk_string[TOX_GROUP_PEER_PUBLIC_KEY_SIZE * 2 + 1] = {0}; |  | ||||||
|  |  | ||||||
|         for (size_t j = 0; j < TOX_GROUP_PEER_PUBLIC_KEY_SIZE; ++j) { |  | ||||||
|             char d[3]; |  | ||||||
|             snprintf(d, sizeof(d), "%02X", peer->public_key[j] & 0xff); |  | ||||||
|             strcat(pk_string, d); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "%s : %s", pk_string, peer->name); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|     uint32_t target_peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Self_Query s_err; |  | ||||||
|     uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err); |  | ||||||
|  |  | ||||||
|     if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to fetch self peer_id."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Mod_Set_Role err; |  | ||||||
|     tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_MODERATOR, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { |  | ||||||
|             groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_MODERATOR); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "You do not have permission to promote moderators."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "%s is already a moderator.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot make yourself a moderator."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to promote peer to moderator (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|     uint32_t target_peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Self_Query s_err; |  | ||||||
|     uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err); |  | ||||||
|  |  | ||||||
|     if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to fetch self peer_id."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (tox_group_peer_get_role(m, self->num, target_peer_id, NULL) != TOX_GROUP_ROLE_MODERATOR) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is not a moderator.", nick); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Mod_Set_Role err; |  | ||||||
|     tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_USER, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { |  | ||||||
|             groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_USER); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "You do not have permission to unmod %s.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot remove your own moderator status."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to revoke moderator powers from %s (error %d).", nick, |  | ||||||
|                           err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_set_passwd(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     const char *passwd = NULL; |  | ||||||
|     size_t len = 0; |  | ||||||
|  |  | ||||||
|     if (argc > 0) { |  | ||||||
|         passwd = argv[1]; |  | ||||||
|         len = strlen(passwd); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Founder_Set_Password err; |  | ||||||
|     tox_group_founder_set_password(m, self->num, (uint8_t *) passwd, len, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK: { |  | ||||||
|             if (len > 0) { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password has been set to %s.", passwd); |  | ||||||
|             } else { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password has been unset."); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password length must not exceed %d.", |  | ||||||
|                           TOX_GROUP_MAX_PASSWORD_SIZE); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the password."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set password (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_set_peerlimit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     int maxpeers = 0; |  | ||||||
|  |  | ||||||
|     if (argc < 1) { |  | ||||||
|         Tox_Err_Group_State_Queries err; |  | ||||||
|         uint32_t maxpeers = tox_group_get_peer_limit(m, self->num, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve peer limit (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer limit is set to %d", maxpeers); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     maxpeers = atoi(argv[1]); |  | ||||||
|  |  | ||||||
|     if (maxpeers <= 0) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer limit must be a value greater than 0."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Founder_Set_Peer_Limit err; |  | ||||||
|     tox_group_founder_set_peer_limit(m, self->num, maxpeers, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer limit has been set to %d.", maxpeers); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the peer limit."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set the peer limit (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_set_voice(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     Tox_Group_Voice_State voice_state; |  | ||||||
|  |  | ||||||
|     if (argc < 1) { |  | ||||||
|         Tox_Err_Group_State_Queries err; |  | ||||||
|         voice_state = tox_group_get_voice_state(m, self->num, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve voice state (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         switch (voice_state) { |  | ||||||
|             case TOX_GROUP_VOICE_STATE_ALL: { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state is set to ALL"); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case TOX_GROUP_VOICE_STATE_MODERATOR: { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state is set to MODERATOR"); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case TOX_GROUP_VOICE_STATE_FOUNDER: { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state is set to FOUNDER"); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             default: |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error: Unknown voice state: %d", voice_state); |  | ||||||
|                 return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *vstate_str = argv[1]; |  | ||||||
|  |  | ||||||
|     if (strcasecmp(vstate_str, "mod") == 0) { |  | ||||||
|         voice_state = TOX_GROUP_VOICE_STATE_MODERATOR; |  | ||||||
|     } else if (strcasecmp(vstate_str, "founder") == 0) { |  | ||||||
|         voice_state = TOX_GROUP_VOICE_STATE_FOUNDER; |  | ||||||
|     } else if (strcasecmp(vstate_str, "all") == 0) { |  | ||||||
|         voice_state = TOX_GROUP_VOICE_STATE_ALL; |  | ||||||
|     } else { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, |  | ||||||
|                       "voice state must be \"all\", \"mod\", or \"founder\"."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Founder_Set_Voice_State err; |  | ||||||
|     tox_group_founder_set_voice_state(m, self->num, voice_state, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state has been set to %s.", vstate_str); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the voice state."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error setting voice state (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_set_privacy(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     const char *pstate_str = NULL; |  | ||||||
|     Tox_Group_Privacy_State privacy_state; |  | ||||||
|  |  | ||||||
|     if (argc < 1) { |  | ||||||
|         Tox_Err_Group_State_Queries err; |  | ||||||
|         privacy_state = tox_group_get_privacy_state(m, self->num, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve privacy state (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         pstate_str = privacy_state == TOX_GROUP_PRIVACY_STATE_PRIVATE ? "private" : "public"; |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Privacy state is set to %s.", pstate_str); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     pstate_str = argv[1]; |  | ||||||
|  |  | ||||||
|     if (strcasecmp(pstate_str, "private") != 0 && strcasecmp(pstate_str, "public") != 0) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Privacy state must be \"private\" or \"public\"."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     privacy_state = strcasecmp(pstate_str, |  | ||||||
|                                "private") == 0 ? TOX_GROUP_PRIVACY_STATE_PRIVATE : TOX_GROUP_PRIVACY_STATE_PUBLIC; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Founder_Set_Privacy_State err; |  | ||||||
|     tox_group_founder_set_privacy_state(m, self->num, privacy_state, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Privacy state has been set to %s.", pstate_str); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the privacy state."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error setting privacy state (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_set_topic_lock(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     Tox_Group_Topic_Lock topic_lock; |  | ||||||
|     const char *tlock_str = NULL; |  | ||||||
|  |  | ||||||
|     if (argc < 1) { |  | ||||||
|         Tox_Err_Group_State_Queries err; |  | ||||||
|         topic_lock = tox_group_get_topic_lock(m, self->num, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic lock (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         tlock_str = topic_lock == TOX_GROUP_TOPIC_LOCK_ENABLED ? "Enabled" : "Disabled"; |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic lock is %s.", tlock_str); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     tlock_str = argv[1]; |  | ||||||
|  |  | ||||||
|     if (strcasecmp(tlock_str, "on") != 0 && strcasecmp(tlock_str, "off") != 0) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic lock must be \"on\" or \"off\"."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     topic_lock = strcasecmp(tlock_str, "on") == 0 ? TOX_GROUP_TOPIC_LOCK_ENABLED : TOX_GROUP_TOPIC_LOCK_DISABLED; |  | ||||||
|     const char *display_str = (topic_lock ==  TOX_GROUP_TOPIC_LOCK_ENABLED) ? "enabled" : "disabled"; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Founder_Set_Topic_Lock err; |  | ||||||
|     tox_group_founder_set_topic_lock(m, self->num, topic_lock, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic lock has been %s.", display_str); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the topic lock."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error setting topic lock (%d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|     uint32_t target_peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Self_Query s_err; |  | ||||||
|     uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err); |  | ||||||
|  |  | ||||||
|     if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to fetch self peer_id."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Mod_Set_Role err; |  | ||||||
|     tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_OBSERVER, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { |  | ||||||
|             groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_OBSERVER); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to silence %s.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is already silenced.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot silence yourself."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to silence %s (error %d).", nick, err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|     uint32_t target_peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (tox_group_peer_get_role(m, self->num, target_peer_id, NULL) != TOX_GROUP_ROLE_OBSERVER) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is not silenced.", nick); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Self_Query s_err; |  | ||||||
|     uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err); |  | ||||||
|  |  | ||||||
|     if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,  "Failed to fetch self peer_id."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Mod_Set_Role err; |  | ||||||
|     tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_USER, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_OK: { |  | ||||||
|             groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_USER); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to unsilence %s.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is not silenced.", nick); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot unsilence yourself."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to unsilence %s (error %d).", nick, err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_rejoin(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     Tox_Err_Group_Reconnect err; |  | ||||||
|  |  | ||||||
|     if (!tox_group_reconnect(m, self->num, &err)) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to rejoin group (error %d).", err); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Reconnecting to group..."); |  | ||||||
|  |  | ||||||
|     groupchat_rejoin(self, m); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         Tox_Err_Group_State_Queries err; |  | ||||||
|         size_t tlen = tox_group_get_topic_size(m, self->num, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic length (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (tlen > 0) { |  | ||||||
|             char cur_topic[TOX_GROUP_MAX_TOPIC_LENGTH + 1]; |  | ||||||
|  |  | ||||||
|             if (!tox_group_get_topic(m, self->num, (uint8_t *) cur_topic, &err)) { |  | ||||||
|                 line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic (error %d).", err); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             cur_topic[tlen] = 0; |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic is set to: %s", cur_topic); |  | ||||||
|         } else { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic is not set."); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *topic = argv[1]; |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Topic_Set err; |  | ||||||
|     tox_group_set_topic(m, self->num, (uint8_t *) topic, strlen(topic), &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_TOPIC_SET_OK: { |  | ||||||
|             /* handled below switch */ |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_TOPIC_SET_TOO_LONG: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic length must not exceed %d.", TOX_GROUP_MAX_TOPIC_LENGTH); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_TOPIC_SET_PERMISSIONS: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the topic."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_TOPIC_SET_DISCONNECTED: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You are disconnected from the group."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set the topic (error %d).", err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     char self_nick[TOX_MAX_NAME_LENGTH + 1]; |  | ||||||
|     get_group_self_nick_truncate(m, self_nick, self->num); |  | ||||||
|  |  | ||||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 1, MAGENTA, "-!- You set the topic to: %s", topic); |  | ||||||
|  |  | ||||||
|     char tmp_event[MAX_STR_SIZE]; |  | ||||||
|     snprintf(tmp_event, sizeof(tmp_event), "set topic to %s", topic); |  | ||||||
|     write_to_log(tmp_event, self_nick, self->chatwin->log, true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *nick = argv[1]; |  | ||||||
|     uint32_t peer_id; |  | ||||||
|  |  | ||||||
|     if (group_get_peer_id_of_identifier(self, nick, &peer_id) != 0) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Tox_Err_Group_Set_Ignore err; |  | ||||||
|     tox_group_set_ignore(m, self->num, peer_id, false, &err); |  | ||||||
|  |  | ||||||
|     switch (err) { |  | ||||||
|         case TOX_ERR_GROUP_SET_IGNORE_OK: { |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_SET_IGNORE_SELF: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot unignore yourself."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         case TOX_ERR_GROUP_SET_IGNORE_PEER_NOT_FOUND: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid."); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         default: { |  | ||||||
|             line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to toggle ignore on %s (error %d).", nick, err); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     line_info_add(self, true, NULL, NULL, SYS_MSG, 1, BLUE, "-!- You are no longer ignoring %s", nick); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cmd_whois(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) |  | ||||||
| { |  | ||||||
|     if (argc < 1) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer must be specified."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     GroupChat *chat = get_groupchat(self->num); |  | ||||||
|  |  | ||||||
|     if (!chat) { |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch GroupChat object."); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const char *identifier = argv[1]; |  | ||||||
|     bool is_public_key = false; |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < chat->max_idx && !is_public_key; ++i) { |  | ||||||
|         uint32_t peer_id; |  | ||||||
|  |  | ||||||
|         if (group_get_public_key_peer_id(self->num, identifier, &peer_id) == 0) { |  | ||||||
|             is_public_key = true; |  | ||||||
|         } else { |  | ||||||
|             GroupPeer *peer = &chat->peer_list[i]; |  | ||||||
|  |  | ||||||
|             if (!peer->active) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (strcmp(identifier, peer->name) != 0) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             peer_id = peer->peer_id; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         int peer_index = get_peer_index(self->num, peer_id); |  | ||||||
|  |  | ||||||
|         if (peer_index < 0) { |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         GroupPeer *peer = &chat->peer_list[peer_index]; |  | ||||||
|  |  | ||||||
|         const char *status_str = "Online"; |  | ||||||
|  |  | ||||||
|         if (peer->status == TOX_USER_STATUS_BUSY) { |  | ||||||
|             status_str = "Busy"; |  | ||||||
|         } else if (peer->status == TOX_USER_STATUS_AWAY) { |  | ||||||
|             status_str = "Away"; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         const char *role_str = "User"; |  | ||||||
|  |  | ||||||
|         if (peer->role == TOX_GROUP_ROLE_FOUNDER) { |  | ||||||
|             role_str = "Founder"; |  | ||||||
|         } else if (peer->role == TOX_GROUP_ROLE_MODERATOR) { |  | ||||||
|             role_str = "Moderator"; |  | ||||||
|         } else if (peer->role == TOX_GROUP_ROLE_OBSERVER) { |  | ||||||
|             role_str = "Observer"; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         char last_seen_str[128]; |  | ||||||
|         get_elapsed_time_str_alt(last_seen_str, sizeof(last_seen_str), |  | ||||||
|                                  get_unix_time() - peer->last_active); |  | ||||||
|  |  | ||||||
|         char pk_string[TOX_GROUP_PEER_PUBLIC_KEY_SIZE * 2 + 1] = {0}; |  | ||||||
|  |  | ||||||
|         for (size_t i = 0; i < TOX_GROUP_PEER_PUBLIC_KEY_SIZE; ++i) { |  | ||||||
|             char d[3]; |  | ||||||
|             snprintf(d, sizeof(d), "%02X", peer->public_key[i] & 0xff); |  | ||||||
|             strcat(pk_string, d); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Tox_Err_Group_Peer_Query conn_err; |  | ||||||
|         Tox_Connection connection_type = tox_group_peer_get_connection_status(m, self->num, peer_id, &conn_err); |  | ||||||
|  |  | ||||||
|         const char *connection_type_str = "Unknown"; |  | ||||||
|  |  | ||||||
|         if (conn_err == TOX_ERR_GROUP_PEER_QUERY_OK || connection_type != TOX_CONNECTION_NONE) { |  | ||||||
|             connection_type_str = connection_type == TOX_CONNECTION_UDP ? "UDP" : "TCP"; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Public key: %s", pk_string); |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Name: %s", peer->name); |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Role: %s", role_str); |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Status: %s", status_str); |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Connection: %s", connection_type_str); |  | ||||||
|         line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Last active: %s", last_seen_str); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| @@ -1,50 +0,0 @@ | |||||||
| /*  groupchat_commands.h |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  *  Copyright (C) 2020 Toxic All Rights Reserved. |  | ||||||
|  * |  | ||||||
|  *  This file is part of Toxic. |  | ||||||
|  * |  | ||||||
|  *  Toxic is free software: you can redistribute it and/or modify |  | ||||||
|  *  it under the terms of the GNU General Public License as published by |  | ||||||
|  *  the Free Software Foundation, either version 3 of the License, or |  | ||||||
|  *  (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  Toxic is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef GROUPCHAT_COMMANDS_H |  | ||||||
| #define GROUPCHAT_COMMANDS_H |  | ||||||
|  |  | ||||||
| #include "windows.h" |  | ||||||
| #include "toxic.h" |  | ||||||
|  |  | ||||||
| void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_disconnect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_list(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_prune(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_set_passwd(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_set_peerlimit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_set_privacy(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_set_voice(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_set_topic_lock(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_rejoin(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
| void cmd_whois(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); |  | ||||||
|  |  | ||||||
| #endif  /* GROUPCHAT_COMMANDS_H */ |  | ||||||
|  |  | ||||||
							
								
								
									
										1836
									
								
								src/groupchats.c
									
									
									
									
									
								
							
							
						
						
									
										1836
									
								
								src/groupchats.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										111
									
								
								src/groupchats.h
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								src/groupchats.h
									
									
									
									
									
								
							| @@ -1,111 +0,0 @@ | |||||||
| /*  groupchats.h |  | ||||||
|  * |  | ||||||
|  * |  | ||||||
|  *  Copyright (C) 2020 Toxic All Rights Reserved. |  | ||||||
|  * |  | ||||||
|  *  This file is part of Toxic. |  | ||||||
|  * |  | ||||||
|  *  Toxic is free software: you can redistribute it and/or modify |  | ||||||
|  *  it under the terms of the GNU General Public License as published by |  | ||||||
|  *  the Free Software Foundation, either version 3 of the License, or |  | ||||||
|  *  (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  *  Toxic is distributed in the hope that it will be useful, |  | ||||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  *  GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  *  You should have received a copy of the GNU General Public License |  | ||||||
|  *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifndef GROUPCHATS_H |  | ||||||
| #define GROUPCHATS_H |  | ||||||
|  |  | ||||||
| #include "toxic.h" |  | ||||||
| #include "windows.h" |  | ||||||
|  |  | ||||||
| #ifndef SIDEWAR_WIDTH |  | ||||||
| #define SIDEBAR_WIDTH 16 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #define MAX_GROUPCHAT_NUM (MAX_WINDOWS_NUM - 2) |  | ||||||
|  |  | ||||||
| typedef enum Group_Join_Type { |  | ||||||
|     Group_Join_Type_Create, |  | ||||||
|     Group_Join_Type_Join, |  | ||||||
|     Group_Join_Type_Load, |  | ||||||
| } Group_Join_Type; |  | ||||||
|  |  | ||||||
| typedef struct GroupPeer { |  | ||||||
|     bool             active; |  | ||||||
|     char             name[TOX_MAX_NAME_LENGTH]; |  | ||||||
|     size_t           name_length; |  | ||||||
|     char             prev_name[TOX_MAX_NAME_LENGTH]; |  | ||||||
|     uint32_t         peer_id; |  | ||||||
|     uint8_t          public_key[TOX_GROUP_PEER_PUBLIC_KEY_SIZE]; |  | ||||||
|     TOX_USER_STATUS  status; |  | ||||||
|     Tox_Group_Role   role; |  | ||||||
|     uint64_t         last_active; |  | ||||||
| } GroupPeer; |  | ||||||
|  |  | ||||||
| typedef struct { |  | ||||||
|     GroupPeer  *peer_list; |  | ||||||
|     char       **name_list;   /* List of peer names, needed for tab completion */ |  | ||||||
|     uint32_t   num_peers;     /* Number of peers in the chat/name_list array */ |  | ||||||
|     uint32_t   max_idx;       /* Maximum peer list index - 1 */ |  | ||||||
|  |  | ||||||
|     char       group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH + 1]; |  | ||||||
|     size_t     group_name_length; |  | ||||||
|     uint32_t   groupnumber; |  | ||||||
|     bool       active; |  | ||||||
|     uint64_t   time_connected;    /* The time we successfully connected to the group */ |  | ||||||
|  |  | ||||||
|     int        chatwin; |  | ||||||
|     int        side_pos;     /* current position of the sidebar - used for scrolling up and down */ |  | ||||||
| } GroupChat; |  | ||||||
|  |  | ||||||
| void exit_groupchat(ToxWindow *self, Tox *m, uint32_t groupnumber, const char *partmessage, size_t length); |  | ||||||
| int init_groupchat_win(Tox *m, uint32_t groupnumber, const char *groupname, size_t length, Group_Join_Type join_type); |  | ||||||
| void set_nick_all_groups(Tox *m, const char *new_nick, size_t length); |  | ||||||
| void set_status_all_groups(Tox *m, uint8_t status); |  | ||||||
| int get_peer_index(uint32_t groupnumber, uint32_t peer_id); |  | ||||||
| void groupchat_onGroupPeerExit(ToxWindow *self, Tox *m, uint32_t groupnumber, uint32_t peer_id, |  | ||||||
|                                Tox_Group_Exit_Type exit_type, |  | ||||||
|                                const char *name, size_t name_len, const char *partmessage, size_t len); |  | ||||||
| void groupchat_onGroupModeration(ToxWindow *self, Tox *m, uint32_t groupnumber, uint32_t src_peer_id, |  | ||||||
|                                  uint32_t tgt_peer_id, Tox_Group_Mod_Event type); |  | ||||||
|  |  | ||||||
| void groupchat_rejoin(ToxWindow *self, Tox *m); |  | ||||||
|  |  | ||||||
| /* Puts the peer_id associated with `identifier` in `peer_id`. The string may be |  | ||||||
|  * either a nick or a public key. |  | ||||||
|  * |  | ||||||
|  * On failure, `peer_id` is set to (uint32_t)-1. |  | ||||||
|  * |  | ||||||
|  * This function is intended to be a helper for groupchat_commands.c and will print |  | ||||||
|  * error messages to `self`. |  | ||||||
|  * Return 0 on success. |  | ||||||
|  * Return -1 if the identifier does not correspond with a peer in the group. |  | ||||||
|  * Return -2 if the identifier is a nick and the nick is in use by multiple peers. |  | ||||||
|  */ |  | ||||||
| int group_get_peer_id_of_identifier(ToxWindow *self, const char *identifier, uint32_t *peer_id); |  | ||||||
|  |  | ||||||
| /* Gets the peer_id associated with `public_key`. |  | ||||||
|  * |  | ||||||
|  * Returns 0 on success. |  | ||||||
|  * Returns -1 on failure or if `public_key` is invalid. |  | ||||||
|  */ |  | ||||||
| int group_get_public_key_peer_id(uint32_t groupnumber, const char *public_key, uint32_t *peer_id); |  | ||||||
|  |  | ||||||
| /* destroys and re-creates groupchat window */ |  | ||||||
| void redraw_groupchat_win(ToxWindow *self); |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Return a GroupChat pointer associated with groupnumber. |  | ||||||
|  * Return NULL if groupnumber is invalid. |  | ||||||
|  */ |  | ||||||
| GroupChat *get_groupchat(uint32_t groupnumber); |  | ||||||
|  |  | ||||||
| #endif /* #define GROUPCHATS_H */ |  | ||||||
							
								
								
									
										58
									
								
								src/help.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/help.c
									
									
									
									
									
								
							| @@ -110,12 +110,6 @@ static void help_draw_menu(ToxWindow *self) | |||||||
|     wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); |     wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); | ||||||
|     wprintw(win, "nference commands\n"); |     wprintw(win, "nference commands\n"); | ||||||
|  |  | ||||||
|     wprintw(win, " g"); |  | ||||||
|     wattron(win, A_BOLD | COLOR_PAIR(BLUE)); |  | ||||||
|     wprintw(win, "r"); |  | ||||||
|     wattroff(win, A_BOLD | COLOR_PAIR(BLUE)); |  | ||||||
|     wprintw(win, "oupchat commands\n"); |  | ||||||
|  |  | ||||||
| #ifdef PYTHON | #ifdef PYTHON | ||||||
|     wattron(win, A_BOLD | COLOR_PAIR(BLUE)); |     wattron(win, A_BOLD | COLOR_PAIR(BLUE)); | ||||||
|     wprintw(win, " p"); |     wprintw(win, " p"); | ||||||
| @@ -177,17 +171,16 @@ static void help_draw_global(ToxWindow *self) | |||||||
|     wprintw(win, "  /add <addr> <msg>          : Add contact with optional message\n"); |     wprintw(win, "  /add <addr> <msg>          : Add contact with optional message\n"); | ||||||
|     wprintw(win, "  /accept <id>               : Accept friend request\n"); |     wprintw(win, "  /accept <id>               : Accept friend request\n"); | ||||||
|     wprintw(win, "  /avatar <path>             : Set an avatar (leave path empty to unset)\n"); |     wprintw(win, "  /avatar <path>             : Set an avatar (leave path empty to unset)\n"); | ||||||
|     wprintw(win, "  /conference <type>         : Create a conference where type: text | audio\n"); |  | ||||||
|     wprintw(win, "  /connect <ip> <port> <key> : Manually connect to a DHT node\n"); |  | ||||||
|     wprintw(win, "  /decline <id>              : Decline friend request\n"); |     wprintw(win, "  /decline <id>              : Decline friend request\n"); | ||||||
|     wprintw(win, "  /requests                  : List pending friend requests\n"); |     wprintw(win, "  /requests                  : List pending friend requests\n"); | ||||||
|  |     wprintw(win, "  /connect <ip> <port> <key> : Manually connect to a DHT node\n"); | ||||||
|     wprintw(win, "  /status <type>             : Set status (Online, Busy, Away)\n"); |     wprintw(win, "  /status <type>             : Set status (Online, Busy, Away)\n"); | ||||||
|     wprintw(win, "  /note <msg>                : Set a personal note\n"); |     wprintw(win, "  /note <msg>                : Set a personal note\n"); | ||||||
|     wprintw(win, "  /nick <nick>               : Set your nickname\n"); |     wprintw(win, "  /nick <nick>               : Set your nickname\n"); | ||||||
|     wprintw(win, "  /nospam <value>            : Change part of your Tox ID to stop spam\n"); |     wprintw(win, "  /nospam <value>            : Change part of your Tox ID to stop spam\n"); | ||||||
|     wprintw(win, "  /log <on> or <off>         : Enable/disable logging\n"); |     wprintw(win, "  /log <on> or <off>         : Enable/disable logging\n"); | ||||||
|  |     wprintw(win, "  /conference <type>         : Create a conference where type: text | audio\n"); | ||||||
|     wprintw(win, "  /myid                      : Print your Tox ID\n"); |     wprintw(win, "  /myid                      : Print your Tox ID\n"); | ||||||
|     wprintw(win, "  /group <name>              : Create a new group chat\n"); |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     wprintw(win, "  /game                      : Play a game\n"); |     wprintw(win, "  /game                      : Play a game\n"); | ||||||
| #endif /* GAMES */ | #endif /* GAMES */ | ||||||
| @@ -285,44 +278,6 @@ static void help_draw_chat(ToxWindow *self) | |||||||
|     wnoutrefresh(win); |     wnoutrefresh(win); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void help_draw_groupchats(ToxWindow *self) |  | ||||||
| { |  | ||||||
|     WINDOW *win = self->help->win; |  | ||||||
|  |  | ||||||
|     wmove(win, 1, 1); |  | ||||||
|  |  | ||||||
|     wattron(win, A_BOLD | COLOR_PAIR(RED)); |  | ||||||
|     wprintw(win, "Groupchat commands:\n"); |  | ||||||
|     wattroff(win, A_BOLD | COLOR_PAIR(RED)); |  | ||||||
|  |  | ||||||
|     wprintw(win, "  /chatid                   : Print this group's ID\n"); |  | ||||||
|     wprintw(win, "  /close <m>                : Leave the group with an optional part message\n"); |  | ||||||
|     wprintw(win, "  /disconnect               : Disconnect from the group (credentials retained)\n"); |  | ||||||
|     wprintw(win, "  /ignore <name>            : Ignore a peer\n"); |  | ||||||
|     wprintw(win, "  /unignore <name>          : Unignore an ignored peer\n"); |  | ||||||
|     wprintw(win, "  /kick <name>              : Remove a peer from the group\n"); |  | ||||||
|     wprintw(win, "  /list                     : Print a list of peers currently in the group\n"); |  | ||||||
|     wprintw(win, "  /locktopic                : Set the topic lock: on | off\n"); |  | ||||||
|     wprintw(win, "  /mod <name>               : Promote a peer to moderator\n"); |  | ||||||
|     wprintw(win, "  /passwd <s>               : Set a password needed to join the group\n"); |  | ||||||
|     wprintw(win, "  /peerlimit <n>            : Set the maximum number of peers that can join\n"); |  | ||||||
|     wprintw(win, "  /privacy <state>          : Set the privacy state: private | public\n"); |  | ||||||
|     wprintw(win, "  /rejoin                   : Reconnect to the groupchat\n"); |  | ||||||
|     wprintw(win, "  /silence <name>           : Silence a peer for the entire group\n"); |  | ||||||
|     wprintw(win, "  /unsilence <name>         : Unsilence a silenced peer\n"); |  | ||||||
|     wprintw(win, "  /status <type>            : Set your status\n"); |  | ||||||
|     wprintw(win, "  /topic <m>                : Set the group topic\n"); |  | ||||||
|     wprintw(win, "  /unmod <name>             : Demote a moderator\n"); |  | ||||||
|     wprintw(win, "  /voice <state>            : Set the voice state: all | mod | founder\n"); |  | ||||||
|     wprintw(win, "  /whisper <name> <m>       : Send a private message to a peer\n"); |  | ||||||
|     wprintw(win, "  /whois <name>             : Print whois info for a peer\n"); |  | ||||||
|  |  | ||||||
|     help_draw_bottom_menu(win); |  | ||||||
|  |  | ||||||
|     box(win, ACS_VLINE, ACS_HLINE); |  | ||||||
|     wnoutrefresh(win); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void help_draw_keys(ToxWindow *self) | static void help_draw_keys(ToxWindow *self) | ||||||
| { | { | ||||||
|     WINDOW *win = self->help->win; |     WINDOW *win = self->help->win; | ||||||
| @@ -488,11 +443,6 @@ void help_onKey(ToxWindow *self, wint_t key) | |||||||
|             help_init_menu(self); |             help_init_menu(self); | ||||||
|             self->help->type = HELP_MENU; |             self->help->type = HELP_MENU; | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case L'r': |  | ||||||
|             help_init_window(self, 26, 80); |  | ||||||
|             self->help->type = HELP_GROUP; |  | ||||||
|             break; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -529,9 +479,5 @@ void help_onDraw(ToxWindow *self) | |||||||
|             help_draw_plugin(self); |             help_draw_plugin(self); | ||||||
|             break; |             break; | ||||||
| #endif /* PYTHON */ | #endif /* PYTHON */ | ||||||
|  |  | ||||||
|         case HELP_GROUP: |  | ||||||
|             help_draw_groupchats(self); |  | ||||||
|             break; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ | |||||||
| typedef enum { | typedef enum { | ||||||
|     HELP_MENU, |     HELP_MENU, | ||||||
|     HELP_GLOBAL, |     HELP_GLOBAL, | ||||||
|     HELP_GROUP, |  | ||||||
|     HELP_CHAT, |     HELP_CHAT, | ||||||
|     HELP_CONFERENCE, |     HELP_CONFERENCE, | ||||||
|     HELP_KEYS, |     HELP_KEYS, | ||||||
|   | |||||||
| @@ -30,7 +30,6 @@ | |||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| #include "notify.h" | #include "notify.h" | ||||||
| #include "groupchats.h" |  | ||||||
| #include "settings.h" | #include "settings.h" | ||||||
| #include "toxic.h" | #include "toxic.h" | ||||||
| #include "toxic_strings.h" | #include "toxic_strings.h" | ||||||
| @@ -338,9 +337,6 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int mx_x) | |||||||
|             if (self->type == WINDOW_TYPE_CONFERENCE) { |             if (self->type == WINDOW_TYPE_CONFERENCE) { | ||||||
|                 self->show_peerlist ^= 1; |                 self->show_peerlist ^= 1; | ||||||
|                 redraw_conference_win(self); |                 redraw_conference_win(self); | ||||||
|             } else if (self->type == WINDOW_TYPE_GROUPCHAT) { |  | ||||||
|                 self->show_peerlist ^= 1; |  | ||||||
|                 redraw_groupchat_win(self); |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             match = true; |             match = true; | ||||||
|   | |||||||
| @@ -30,7 +30,6 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| #include "conference.h" | #include "conference.h" | ||||||
| #include "groupchats.h" |  | ||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "message_queue.h" | #include "message_queue.h" | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| @@ -422,29 +421,18 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const | |||||||
|     switch (type) { |     switch (type) { | ||||||
|         case IN_ACTION: |         case IN_ACTION: | ||||||
|  |  | ||||||
|         /* fallthrough */ |  | ||||||
|         case OUT_ACTION_READ: |  | ||||||
|  |  | ||||||
|         /* fallthrough */ |         /* fallthrough */ | ||||||
|         case OUT_ACTION: |         case OUT_ACTION: | ||||||
|             len += strlen(user_settings->line_normal) + 2; // two spaces |             len += strlen(user_settings->line_normal) + 2; // two spaces | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case IN_MSG: |         case IN_MSG: | ||||||
|         case OUT_MSG_READ: |  | ||||||
|  |  | ||||||
|         /* fallthrough */ |         /* fallthrough */ | ||||||
|         case OUT_MSG: |         case OUT_MSG: | ||||||
|             len += strlen(user_settings->line_normal) + 3; // two spaces and a ':' char |             len += strlen(user_settings->line_normal) + 3; // two spaces and a ':' char | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case IN_PRVT_MSG: |  | ||||||
|  |  | ||||||
|         /* fallthrough */ |  | ||||||
|         case OUT_PRVT_MSG: |  | ||||||
|             len += strlen(user_settings->line_special) + 3; |  | ||||||
|             break; |  | ||||||
|  |  | ||||||
|         case CONNECTION: |         case CONNECTION: | ||||||
|             len += strlen(user_settings->line_join) + 2;  // two spaces |             len += strlen(user_settings->line_join) + 2;  // two spaces | ||||||
|             break; |             break; | ||||||
| @@ -558,7 +546,7 @@ void line_info_print(ToxWindow *self) | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (self->type == WINDOW_TYPE_CONFERENCE || self->type == WINDOW_TYPE_GROUPCHAT) { |     if (self->type == WINDOW_TYPE_CONFERENCE) { | ||||||
|         wmove(win, 0, 0); |         wmove(win, 0, 0); | ||||||
|     } else { |     } else { | ||||||
|         wmove(win, TOP_BAR_HEIGHT, 0); |         wmove(win, TOP_BAR_HEIGHT, 0); | ||||||
| @@ -594,7 +582,7 @@ void line_info_print(ToxWindow *self) | |||||||
|             case OUT_MSG_READ: |             case OUT_MSG_READ: | ||||||
|  |  | ||||||
|             /* fallthrough */ |             /* fallthrough */ | ||||||
|             case IN_MSG: { |             case IN_MSG: | ||||||
|                 wattron(win, COLOR_PAIR(BLUE)); |                 wattron(win, COLOR_PAIR(BLUE)); | ||||||
|                 wprintw(win, "%s ", line->timestr); |                 wprintw(win, "%s ", line->timestr); | ||||||
|                 wattroff(win, COLOR_PAIR(BLUE)); |                 wattroff(win, COLOR_PAIR(BLUE)); | ||||||
| @@ -632,49 +620,6 @@ void line_info_print(ToxWindow *self) | |||||||
|  |  | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case IN_PRVT_MSG: |  | ||||||
|  |  | ||||||
|             /* fallthrough */ |  | ||||||
|  |  | ||||||
|             case OUT_PRVT_MSG: { |  | ||||||
|                 wattron(win, COLOR_PAIR(BLUE)); |  | ||||||
|                 wprintw(win, "%s ", line->timestr); |  | ||||||
|                 wattroff(win, COLOR_PAIR(BLUE)); |  | ||||||
|  |  | ||||||
|                 int nameclr = GREEN; |  | ||||||
|  |  | ||||||
|                 if (line->colour) { |  | ||||||
|                     nameclr = line->colour; |  | ||||||
|                 } else if (type == IN_MSG) { |  | ||||||
|                     nameclr = CYAN; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 wattron(win, COLOR_PAIR(nameclr)); |  | ||||||
|                 wprintw(win, "%s %s: ", (type != OUT_PRVT_MSG && type != IN_PRVT_MSG) ? |  | ||||||
|                         user_settings->line_normal : |  | ||||||
|                         user_settings->line_special, |  | ||||||
|                         line->name1); |  | ||||||
|                 wattroff(win, COLOR_PAIR(nameclr)); |  | ||||||
|  |  | ||||||
|                 if (line->msg[0] == '>') { |  | ||||||
|                     wattron(win, COLOR_PAIR(GREEN)); |  | ||||||
|                 } else if (line->msg[0] == '<') { |  | ||||||
|                     wattron(win, COLOR_PAIR(RED)); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 print_wrap(win, line, max_x, max_y); |  | ||||||
|  |  | ||||||
|                 if (line->msg[0] == '>') { |  | ||||||
|                     wattroff(win, COLOR_PAIR(GREEN)); |  | ||||||
|                 } else if (line->msg[0] == '<') { |  | ||||||
|                     wattroff(win, COLOR_PAIR(RED)); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 waddch(win, '\n'); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case OUT_ACTION_READ: |             case OUT_ACTION_READ: | ||||||
|  |  | ||||||
| @@ -682,7 +627,7 @@ void line_info_print(ToxWindow *self) | |||||||
|             case OUT_ACTION: |             case OUT_ACTION: | ||||||
|  |  | ||||||
|             /* fallthrough */ |             /* fallthrough */ | ||||||
|             case IN_ACTION: { |             case IN_ACTION: | ||||||
|                 wattron(win, COLOR_PAIR(BLUE)); |                 wattron(win, COLOR_PAIR(BLUE)); | ||||||
|                 wprintw(win, "%s ", line->timestr); |                 wprintw(win, "%s ", line->timestr); | ||||||
|                 wattroff(win, COLOR_PAIR(BLUE)); |                 wattroff(win, COLOR_PAIR(BLUE)); | ||||||
| @@ -694,9 +639,8 @@ void line_info_print(ToxWindow *self) | |||||||
|  |  | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case SYS_MSG: { |             case SYS_MSG: | ||||||
|                 if (line->timestr[0]) { |                 if (line->timestr[0]) { | ||||||
|                     wattron(win, COLOR_PAIR(BLUE)); |                     wattron(win, COLOR_PAIR(BLUE)); | ||||||
|                     wprintw(win, "%s ", line->timestr); |                     wprintw(win, "%s ", line->timestr); | ||||||
| @@ -723,9 +667,8 @@ void line_info_print(ToxWindow *self) | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case PROMPT: { |             case PROMPT: | ||||||
|                 wattron(win, COLOR_PAIR(GREEN)); |                 wattron(win, COLOR_PAIR(GREEN)); | ||||||
|                 wprintw(win, "$ "); |                 wprintw(win, "$ "); | ||||||
|                 wattroff(win, COLOR_PAIR(GREEN)); |                 wattroff(win, COLOR_PAIR(GREEN)); | ||||||
| @@ -736,9 +679,8 @@ void line_info_print(ToxWindow *self) | |||||||
|  |  | ||||||
|                 waddch(win, '\n'); |                 waddch(win, '\n'); | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case CONNECTION: { |             case CONNECTION: | ||||||
|                 wattron(win, COLOR_PAIR(BLUE)); |                 wattron(win, COLOR_PAIR(BLUE)); | ||||||
|                 wprintw(win, "%s ", line->timestr); |                 wprintw(win, "%s ", line->timestr); | ||||||
|                 wattroff(win, COLOR_PAIR(BLUE)); |                 wattroff(win, COLOR_PAIR(BLUE)); | ||||||
| @@ -756,9 +698,8 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wattroff(win, COLOR_PAIR(line->colour)); |                 wattroff(win, COLOR_PAIR(line->colour)); | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case DISCONNECTION: { |             case DISCONNECTION: | ||||||
|                 wattron(win, COLOR_PAIR(BLUE)); |                 wattron(win, COLOR_PAIR(BLUE)); | ||||||
|                 wprintw(win, "%s ", line->timestr); |                 wprintw(win, "%s ", line->timestr); | ||||||
|                 wattroff(win, COLOR_PAIR(BLUE)); |                 wattroff(win, COLOR_PAIR(BLUE)); | ||||||
| @@ -776,9 +717,8 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wattroff(win, COLOR_PAIR(line->colour)); |                 wattroff(win, COLOR_PAIR(line->colour)); | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|  |  | ||||||
|             case NAME_CHANGE: { |             case NAME_CHANGE: | ||||||
|                 wattron(win, COLOR_PAIR(BLUE)); |                 wattron(win, COLOR_PAIR(BLUE)); | ||||||
|                 wprintw(win, "%s ", line->timestr); |                 wprintw(win, "%s ", line->timestr); | ||||||
|                 wattroff(win, COLOR_PAIR(BLUE)); |                 wattroff(win, COLOR_PAIR(BLUE)); | ||||||
| @@ -797,7 +737,6 @@ void line_info_print(ToxWindow *self) | |||||||
|                 wattroff(win, COLOR_PAIR(MAGENTA)); |                 wattroff(win, COLOR_PAIR(MAGENTA)); | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         line = line->next; |         line = line->next; | ||||||
|   | |||||||
| @@ -39,8 +39,6 @@ typedef enum LINE_TYPE { | |||||||
|     IN_ACTION, |     IN_ACTION, | ||||||
|     OUT_ACTION, |     OUT_ACTION, | ||||||
|     OUT_ACTION_READ,     /* same as OUT_MSG_READ but for actions */ |     OUT_ACTION_READ,     /* same as OUT_MSG_READ but for actions */ | ||||||
|     IN_PRVT_MSG,   /* PRVT should only be used for groups */ |  | ||||||
|     OUT_PRVT_MSG, |  | ||||||
|     PROMPT, |     PROMPT, | ||||||
|     CONNECTION, |     CONNECTION, | ||||||
|     DISCONNECTION, |     DISCONNECTION, | ||||||
|   | |||||||
| @@ -136,26 +136,6 @@ void get_elapsed_time_str(char *buf, int bufsize, time_t secs) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Converts seconds to string in format H hours, m minutes, s seconds */ |  | ||||||
| void get_elapsed_time_str_alt(char *buf, int bufsize, uint64_t secs) |  | ||||||
| { |  | ||||||
|     if (!secs) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     long int seconds = secs % 60; |  | ||||||
|     long int minutes = (secs % 3600) / 60; |  | ||||||
|     long int hours = secs / 3600; |  | ||||||
|  |  | ||||||
|     if (!minutes && !hours) { |  | ||||||
|         snprintf(buf, bufsize, "%ld seconds", seconds); |  | ||||||
|     } else if (!hours) { |  | ||||||
|         snprintf(buf, bufsize, "%ld minutes, %ld seconds", minutes, seconds); |  | ||||||
|     } else { |  | ||||||
|         snprintf(buf, bufsize, "%ld hours, %ld minutes, %ld seconds", hours, minutes, seconds); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Converts a hexidecimal string representation of a Tox public key to binary format and puts |  * Converts a hexidecimal string representation of a Tox public key to binary format and puts | ||||||
|  * the result in output. |  * the result in output. | ||||||
| @@ -490,59 +470,6 @@ on_error: | |||||||
|     strcpy(buf, UNKNOWN_NAME); |     strcpy(buf, UNKNOWN_NAME); | ||||||
|     len = strlen(UNKNOWN_NAME); |     len = strlen(UNKNOWN_NAME); | ||||||
|     buf[len] = '\0'; |     buf[len] = '\0'; | ||||||
|  |  | ||||||
|     return len; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* same as get_nick_truncate but for groupchats */ |  | ||||||
| size_t get_group_nick_truncate(Tox *m, char *buf, uint32_t peer_id, uint32_t groupnum) |  | ||||||
| { |  | ||||||
|     Tox_Err_Group_Peer_Query err; |  | ||||||
|     size_t len = tox_group_peer_get_name_size(m, groupnum, peer_id, &err); |  | ||||||
|  |  | ||||||
|     if (err != TOX_ERR_GROUP_PEER_QUERY_OK || len == 0) { |  | ||||||
|         strcpy(buf, UNKNOWN_NAME); |  | ||||||
|         len = strlen(UNKNOWN_NAME); |  | ||||||
|     } else { |  | ||||||
|         tox_group_peer_get_name(m, groupnum, peer_id, (uint8_t *) buf, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_PEER_QUERY_OK) { |  | ||||||
|             strcpy(buf, UNKNOWN_NAME); |  | ||||||
|             len = strlen(UNKNOWN_NAME); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); |  | ||||||
|     buf[len] = '\0'; |  | ||||||
|  |  | ||||||
|     filter_str(buf, len); |  | ||||||
|  |  | ||||||
|     return len; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* same as get_group_nick_truncate() but for self. */ |  | ||||||
| size_t get_group_self_nick_truncate(Tox *m, char *buf, uint32_t groupnum) |  | ||||||
| { |  | ||||||
|     Tox_Err_Group_Self_Query err; |  | ||||||
|     size_t len = tox_group_self_get_name_size(m, groupnum, &err); |  | ||||||
|  |  | ||||||
|     if (err != TOX_ERR_GROUP_SELF_QUERY_OK) { |  | ||||||
|         strcpy(buf, UNKNOWN_NAME); |  | ||||||
|         len = strlen(UNKNOWN_NAME); |  | ||||||
|     } else { |  | ||||||
|         tox_group_self_get_name(m, groupnum, (uint8_t *) buf, &err); |  | ||||||
|  |  | ||||||
|         if (err != TOX_ERR_GROUP_SELF_QUERY_OK) { |  | ||||||
|             strcpy(buf, UNKNOWN_NAME); |  | ||||||
|             len = strlen(UNKNOWN_NAME); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); |  | ||||||
|     buf[len] = 0; |  | ||||||
|  |  | ||||||
|     filter_str(buf, len); |  | ||||||
|  |  | ||||||
|     return len; |     return len; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -678,8 +605,7 @@ void set_window_title(ToxWindow *self, const char *title, int len) | |||||||
|  |  | ||||||
|     char cpy[TOXIC_MAX_NAME_LENGTH + 1]; |     char cpy[TOXIC_MAX_NAME_LENGTH + 1]; | ||||||
|  |  | ||||||
|     /* keep conferencenumber in title */ |     if (self->type == WINDOW_TYPE_CONFERENCE) { /* keep conferencenumber in title for invites */ | ||||||
|     if (self->type == WINDOW_TYPE_CONFERENCE || self->type == WINDOW_TYPE_GROUPCHAT) { |  | ||||||
|         snprintf(cpy, sizeof(cpy), "%u %s", self->num, title); |         snprintf(cpy, sizeof(cpy), "%u %s", self->num, title); | ||||||
|     } else { |     } else { | ||||||
|         snprintf(cpy, sizeof(cpy), "%s", title); |         snprintf(cpy, sizeof(cpy), "%s", title); | ||||||
|   | |||||||
| @@ -97,9 +97,6 @@ time_t get_unix_time(void); | |||||||
| /* Puts the current time in buf in the format of specified by the config */ | /* Puts the current time in buf in the format of specified by the config */ | ||||||
| void get_time_str(char *buf, size_t bufsize); | void get_time_str(char *buf, size_t bufsize); | ||||||
|  |  | ||||||
| /* Converts seconds to string in format H hours, m minutes, s seconds */ |  | ||||||
| void get_elapsed_time_str_alt(char *buf, int bufsize, uint64_t secs); |  | ||||||
|  |  | ||||||
| /* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */ | /* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */ | ||||||
| void get_elapsed_time_str(char *buf, int bufsize, time_t secs); | void get_elapsed_time_str(char *buf, int bufsize, time_t secs); | ||||||
|  |  | ||||||
| @@ -171,12 +168,6 @@ size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum); | |||||||
| /* same as get_nick_truncate but for conferences */ | /* same as get_nick_truncate but for conferences */ | ||||||
| int get_conference_nick_truncate(Tox *m, char *buf, uint32_t peernum, uint32_t conferencenum); | int get_conference_nick_truncate(Tox *m, char *buf, uint32_t peernum, uint32_t conferencenum); | ||||||
|  |  | ||||||
| /* same as get_nick_truncate but for groupchats */ |  | ||||||
| size_t get_group_nick_truncate(Tox *m, char *buf, uint32_t peer_id, uint32_t groupnum); |  | ||||||
|  |  | ||||||
| /* same as get_group_nick_truncate() but for self. */ |  | ||||||
| size_t get_group_self_nick_truncate(Tox *m, char *buf, uint32_t groupnum); |  | ||||||
|  |  | ||||||
| /* copies data to msg buffer. | /* copies data to msg buffer. | ||||||
|    returns length of msg, which will be no larger than size-1 */ |    returns length of msg, which will be no larger than size-1 */ | ||||||
| size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length); | size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length); | ||||||
|   | |||||||
							
								
								
									
										299
									
								
								src/netprof.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								src/netprof.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | |||||||
|  | /*  netprof.c | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2022 Toxic All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  This file is part of Toxic. | ||||||
|  |  * | ||||||
|  |  *  Toxic is free software: you can redistribute it and/or modify | ||||||
|  |  *  it under the terms of the GNU General Public License as published by | ||||||
|  |  *  the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *  (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  Toxic is distributed in the hope that it will be useful, | ||||||
|  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *  GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #include "netprof.h" | ||||||
|  |  | ||||||
|  | #include "../../toxcore/toxcore/tox_private.h"  // set this to your local toxcore source directory | ||||||
|  |  | ||||||
|  | static void log_tcp_packet_id(FILE *fp, unsigned int id, uint64_t total, uint64_t TCP_id_sent, uint64_t TCP_id_recv) | ||||||
|  | { | ||||||
|  |     switch (id) { | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ZERO: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONE: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TWO: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_DISCONNECT: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_FOUR: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_PONG: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_OOB_SEND: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_OOB_RECV: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TCP_DATA: { | ||||||
|  |             if (TCP_id_recv || TCP_id_sent) { | ||||||
|  |                 fprintf(fp, "0x%02x (total):     %lu (%.2f%%)\n", id, TCP_id_sent + TCP_id_recv, | ||||||
|  |                         ((float)TCP_id_recv + TCP_id_sent) / total * 100.0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (TCP_id_sent) { | ||||||
|  |                 fprintf(fp, "0x%02x (sent):      %lu (%.2f%%)\n", id, TCP_id_sent, (float)TCP_id_sent / total * 100.0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (TCP_id_recv) { | ||||||
|  |                 fprintf(fp, "0x%02x (recv):      %lu (%.2f%%)\n", id, TCP_id_recv, (float)TCP_id_recv / total * 100.0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |             return; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | static void log_udp_packet_id(FILE *fp, unsigned int id, uint64_t total, uint64_t UDP_id_sent, uint64_t UDP_id_recv) | ||||||
|  | { | ||||||
|  |     switch (id) { | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ZERO: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONE: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_TWO: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_FOUR: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_COOKIE_REQUEST: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_CRYPTO_HS: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_CRYPTO_DATA: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_CRYPTO: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_LAN_DISCOVERY: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_SEND_1: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_SEND_2: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_RECV_3: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_RECV_2: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_ONION_RECV_1: | ||||||
|  |         case TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO: { | ||||||
|  |             if (UDP_id_recv || UDP_id_sent) { | ||||||
|  |                 fprintf(fp, "0x%02x (total):     %lu (%.2f%%)\n", id, UDP_id_sent + UDP_id_recv, | ||||||
|  |                         ((float)UDP_id_recv + UDP_id_sent) / total * 100.0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (UDP_id_sent) { | ||||||
|  |                 fprintf(fp, "0x%02x (sent):      %lu (%.2f%%)\n", id, UDP_id_sent, (float)UDP_id_sent / total * 100.0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (UDP_id_recv) { | ||||||
|  |                 fprintf(fp, "0x%02x (recv):      %lu (%.2f%%)\n", id, UDP_id_recv, (float)UDP_id_recv / total * 100.0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         default: | ||||||
|  |             return; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void dump_packet_id_counts(const Tox *m, FILE *fp, uint64_t total_count, Tox_Netprof_Packet_Type packet_type) | ||||||
|  | { | ||||||
|  |     if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) { | ||||||
|  |         fprintf(fp, "--- TCP packet counts by packet ID --- \n"); | ||||||
|  |     } else { | ||||||
|  |         fprintf(fp, "--- UDP packet counts by packet ID --- \n"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (unsigned long i = TOX_NETPROF_PACKET_ID_ZERO; i <= TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO; ++i) { | ||||||
|  |         const uint64_t id_count_sent = tox_netprof_get_packet_id_count(m, packet_type, i, TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |         const uint64_t id_count_recv = tox_netprof_get_packet_id_count(m, packet_type, i, TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |  | ||||||
|  |         if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) { | ||||||
|  |             log_tcp_packet_id(fp, i, total_count, id_count_sent, id_count_recv); | ||||||
|  |         } else { | ||||||
|  |             log_udp_packet_id(fp, i, total_count, id_count_sent, id_count_recv); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fprintf(fp, "\n\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void dump_packet_id_bytes(const Tox *m, FILE *fp, uint64_t total_bytes, Tox_Netprof_Packet_Type packet_type) | ||||||
|  | { | ||||||
|  |     if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) { | ||||||
|  |         fprintf(fp, "--- TCP byte counts by packet ID --- \n"); | ||||||
|  |     } else { | ||||||
|  |         fprintf(fp, "--- UDP byte counts by packet ID --- \n"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for (unsigned long i = TOX_NETPROF_PACKET_ID_ZERO; i <= TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO; ++i) { | ||||||
|  |         const uint64_t id_bytes_sent = tox_netprof_get_packet_id_bytes(m, packet_type, i, TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |         const uint64_t id_bytes_recv = tox_netprof_get_packet_id_bytes(m, packet_type, i, TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |  | ||||||
|  |         if (packet_type == TOX_NETPROF_PACKET_TYPE_TCP) { | ||||||
|  |             log_tcp_packet_id(fp, i, total_bytes, id_bytes_sent, id_bytes_recv); | ||||||
|  |         } else { | ||||||
|  |             log_udp_packet_id(fp, i, total_bytes, id_bytes_sent, id_bytes_recv); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fprintf(fp, "\n\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void dump_packet_count_totals(const Tox *m, FILE *fp, uint64_t total_packet_count, | ||||||
|  |                                      uint64_t UDP_count_sent, uint64_t UDP_count_recv, | ||||||
|  |                                      uint64_t TCP_count_sent, uint64_t TCP_count_recv) | ||||||
|  | { | ||||||
|  |     const uint64_t total_UDP_count = UDP_count_sent + UDP_count_recv; | ||||||
|  |     const uint64_t total_TCP_count = TCP_count_sent + TCP_count_recv; | ||||||
|  |     const uint64_t total_packet_count_sent = UDP_count_sent + TCP_count_sent; | ||||||
|  |     const uint64_t total_packet_count_recv = UDP_count_recv + TCP_count_recv; | ||||||
|  |  | ||||||
|  |     fprintf(fp, "--- Total packet counts --- \n"); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total packets:          %lu\n", total_packet_count); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total packets sent:     %lu (%.2f%%)\n", total_packet_count_sent, | ||||||
|  |             (float)total_packet_count_sent / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total packets recv:     %lu (%.2f%%)\n", total_packet_count_recv, | ||||||
|  |             (float)total_packet_count_recv / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "total UDP packets:      %lu (%.2f%%)\n", total_UDP_count, | ||||||
|  |             (float)total_UDP_count / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "UDP packets sent:       %lu (%.2f%%)\n", UDP_count_sent, | ||||||
|  |             (float)UDP_count_sent / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "UDP packets recv:       %lu (%.2f%%)\n", UDP_count_recv, | ||||||
|  |             (float)UDP_count_recv / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total TCP packets:      %lu (%.2f%%)\n", total_TCP_count, | ||||||
|  |             (float)total_TCP_count / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "TCP packets sent:       %lu (%.2f%%)\n", TCP_count_sent, | ||||||
|  |             (float)TCP_count_sent / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "TCP packets recv:       %lu (%.2f%%)\n", TCP_count_recv, | ||||||
|  |             (float)TCP_count_recv / total_packet_count * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "\n\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void dump_packet_bytes_totals(const Tox *m, FILE *fp, const uint64_t total_bytes, | ||||||
|  |                               const uint64_t UDP_bytes_sent, const uint64_t UDP_bytes_recv, | ||||||
|  |                               const uint64_t TCP_bytes_sent, const uint64_t TCP_bytes_recv) | ||||||
|  | { | ||||||
|  |     const uint64_t total_UDP_bytes = UDP_bytes_sent + UDP_bytes_recv; | ||||||
|  |     const uint64_t total_TCP_bytes = TCP_bytes_sent + TCP_bytes_recv; | ||||||
|  |     const uint64_t total_bytes_sent = UDP_bytes_sent + TCP_bytes_sent; | ||||||
|  |     const uint64_t total_bytes_recv = UDP_bytes_recv + TCP_bytes_recv; | ||||||
|  |  | ||||||
|  |     fprintf(fp, "--- Total byte counts --- \n"); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total bytes:            %lu\n", total_bytes); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total bytes sent:       %lu (%.2f%%)\n", total_bytes_sent, | ||||||
|  |             (float)total_bytes_sent / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total bytes recv:       %lu (%.2f%%)\n", total_bytes_recv, | ||||||
|  |             (float)total_bytes_recv / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total UDP bytes:        %lu (%.2f%%)\n", total_UDP_bytes, | ||||||
|  |             (float)total_UDP_bytes / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "UDP bytes sent:         %lu (%.2f%%)\n", UDP_bytes_sent, | ||||||
|  |             (float)UDP_bytes_sent / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "UDP bytes recv:         %lu (%.2f%%)\n", UDP_bytes_recv, | ||||||
|  |             (float)UDP_bytes_recv / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "Total TCP bytes:        %lu (%.2f%%)\n", total_TCP_bytes, | ||||||
|  |             (float)total_TCP_bytes / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "TCP bytes sent:         %lu (%.2f%%)\n", TCP_bytes_sent, | ||||||
|  |             (float)TCP_bytes_sent / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "TCP bytes recv:         %lu (%.2f%%)\n", TCP_bytes_recv, | ||||||
|  |             (float)TCP_bytes_recv / total_bytes * 100.0); | ||||||
|  |  | ||||||
|  |     fprintf(fp, "\n\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void netprof_log_dump(const Tox *m, FILE *fp, time_t run_time) | ||||||
|  | { | ||||||
|  |     if (fp == NULL) { | ||||||
|  |         fprintf(stderr, "Failed to dump network statistics: null file pointer\n"); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const uint64_t UDP_count_sent = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_UDP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |     const uint64_t UDP_count_recv = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_UDP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |     const uint64_t TCP_count_sent = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_TCP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |     const uint64_t TCP_count_recv = tox_netprof_get_packet_total_count(m, TOX_NETPROF_PACKET_TYPE_TCP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |     const uint64_t UDP_bytes_sent = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_UDP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |     const uint64_t UDP_bytes_recv = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_UDP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |     const uint64_t TCP_bytes_sent = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_TCP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |     const uint64_t TCP_bytes_recv = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_TCP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |  | ||||||
|  |     const uint64_t total_count = UDP_count_sent + UDP_count_recv + TCP_count_sent + TCP_count_recv; | ||||||
|  |     const uint64_t total_bytes = UDP_bytes_sent + UDP_bytes_recv + TCP_bytes_sent + TCP_bytes_recv; | ||||||
|  |  | ||||||
|  |     fprintf(fp, "--- Tox network profile log dump ---\n"); | ||||||
|  |     fprintf(fp, "Run time: %lu seconds\n", run_time); | ||||||
|  |  | ||||||
|  |     if (run_time && total_count && total_bytes) { | ||||||
|  |         fprintf(fp, "Average kilobytes per second: %.2f\n", ((float)total_bytes / run_time) / 1000.0); | ||||||
|  |         fprintf(fp, "Average packets per second: %lu\n", total_count / run_time); | ||||||
|  |         fprintf(fp, "Average packet size: %lu bytes\n", total_bytes / total_count); | ||||||
|  |         fprintf(fp, "\n"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     dump_packet_count_totals(m, fp, total_count, UDP_count_sent, UDP_count_recv, TCP_count_sent, TCP_count_recv); | ||||||
|  |     dump_packet_bytes_totals(m, fp, total_bytes, UDP_bytes_sent, UDP_bytes_recv, TCP_bytes_sent, TCP_bytes_recv); | ||||||
|  |     dump_packet_id_counts(m, fp, total_count, TOX_NETPROF_PACKET_TYPE_TCP); | ||||||
|  |     dump_packet_id_counts(m, fp, total_count, TOX_NETPROF_PACKET_TYPE_UDP); | ||||||
|  |     dump_packet_id_bytes(m, fp, total_bytes, TOX_NETPROF_PACKET_TYPE_TCP); | ||||||
|  |     dump_packet_id_bytes(m, fp, total_bytes, TOX_NETPROF_PACKET_TYPE_UDP); | ||||||
|  |  | ||||||
|  |     fflush(fp); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint64_t netprof_get_bytes_up(const Tox *m) | ||||||
|  | { | ||||||
|  |     const uint64_t UDP_bytes_sent = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_UDP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |     const uint64_t TCP_bytes_sent = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_TCP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_SENT); | ||||||
|  |  | ||||||
|  |     return UDP_bytes_sent + TCP_bytes_sent; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint64_t netprof_get_bytes_down(const Tox *m) | ||||||
|  | { | ||||||
|  |     const uint64_t UDP_bytes_recv = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_UDP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |     const uint64_t TCP_bytes_recv = tox_netprof_get_packet_total_bytes(m, TOX_NETPROF_PACKET_TYPE_TCP, | ||||||
|  |                                     TOX_NETPROF_DIRECTION_RECV); | ||||||
|  |  | ||||||
|  |     return UDP_bytes_recv + TCP_bytes_recv; | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								src/netprof.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/netprof.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | /*  netprof.h | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2022 Toxic All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  This file is part of Toxic. | ||||||
|  |  * | ||||||
|  |  *  Toxic is free software: you can redistribute it and/or modify | ||||||
|  |  *  it under the terms of the GNU General Public License as published by | ||||||
|  |  *  the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  *  (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  *  Toxic is distributed in the hope that it will be useful, | ||||||
|  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  *  GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  *  You should have received a copy of the GNU General Public License | ||||||
|  |  *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef TOXIC_NETPROF | ||||||
|  | #define TOXIC_NETPROF | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <tox/tox.h> | ||||||
|  |  | ||||||
|  | void netprof_log_dump(const Tox *m, FILE *fp, time_t run_time); | ||||||
|  |  | ||||||
|  | uint64_t netprof_get_bytes_down(const Tox *m); | ||||||
|  | uint64_t netprof_get_bytes_up(const Tox *m); | ||||||
|  |  | ||||||
|  | #endif  // TOXIC_NETPROF | ||||||
							
								
								
									
										78
									
								
								src/prompt.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/prompt.c
									
									
									
									
									
								
							| @@ -36,6 +36,7 @@ | |||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "log.h" | #include "log.h" | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
|  | #include "netprof.h" | ||||||
| #include "notify.h" | #include "notify.h" | ||||||
| #include "prompt.h" | #include "prompt.h" | ||||||
| #include "settings.h" | #include "settings.h" | ||||||
| @@ -59,13 +60,11 @@ static const char *glob_cmd_list[] = { | |||||||
|     "/connect", |     "/connect", | ||||||
|     "/decline", |     "/decline", | ||||||
|     "/exit", |     "/exit", | ||||||
|     "/group", |  | ||||||
|     "/conference", |     "/conference", | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
|     "/game", |     "/game", | ||||||
| #endif | #endif | ||||||
|     "/help", |     "/help", | ||||||
|     "/join", |  | ||||||
|     "/log", |     "/log", | ||||||
|     "/myid", |     "/myid", | ||||||
| #ifdef QRCODE | #ifdef QRCODE | ||||||
| @@ -307,6 +306,77 @@ static bool prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) | |||||||
|     return input_ret; |     return input_ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #define NET_INFO_REFRESH_INTERVAL 1 | ||||||
|  | static void draw_network_info(const Tox *m, StatusBar *stb) | ||||||
|  | { | ||||||
|  |     WINDOW *win = stb->topline; | ||||||
|  |  | ||||||
|  |     wattron(win, COLOR_PAIR(BAR_TEXT)); | ||||||
|  |     wprintw(win, "%s", stb->network_info); | ||||||
|  |     wattroff(win, COLOR_PAIR(BAR_TEXT)); | ||||||
|  |  | ||||||
|  |     if (!timed_out(stb->time_last_refreshed, NET_INFO_REFRESH_INTERVAL)) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     stb->time_last_refreshed = get_unix_time(); | ||||||
|  |  | ||||||
|  |     const uint64_t up_bytes = netprof_get_bytes_up(m); | ||||||
|  |     const uint64_t down_bytes = netprof_get_bytes_down(m); | ||||||
|  |  | ||||||
|  |     const uint64_t up_delta = (up_bytes - stb->up_bytes) / NET_INFO_REFRESH_INTERVAL; | ||||||
|  |     const uint64_t down_delta = (down_bytes - stb->down_bytes) / NET_INFO_REFRESH_INTERVAL; | ||||||
|  |  | ||||||
|  |     stb->up_bytes = up_bytes; | ||||||
|  |     stb->down_bytes = down_bytes; | ||||||
|  |  | ||||||
|  |     float up = up_bytes; | ||||||
|  |     float down = down_bytes; | ||||||
|  |     const char *up_unit = "bytes"; | ||||||
|  |     const char *down_unit = "bytes"; | ||||||
|  |  | ||||||
|  |     if (up_bytes > MiB) { | ||||||
|  |         up /= (float)MiB; | ||||||
|  |         up_unit = "MiB"; | ||||||
|  |     } else if (up_bytes > KiB) { | ||||||
|  |         up /= (float)KiB; | ||||||
|  |         up_unit = "KiB"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (down_bytes > MiB) { | ||||||
|  |         down /= (float)MiB; | ||||||
|  |         down_unit = "MiB"; | ||||||
|  |     } else if (down_bytes > KiB) { | ||||||
|  |         down /= (float)KiB; | ||||||
|  |         down_unit = "KiB"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     float up_bps = up_delta; | ||||||
|  |     float down_bps = down_delta; | ||||||
|  |     const char *up_bps_unit = "b/s"; | ||||||
|  |     const char *down_bps_unit = "b/s"; | ||||||
|  |  | ||||||
|  |     if (up_bps > MiB) { | ||||||
|  |         up_bps /= (float)MiB; | ||||||
|  |         up_bps_unit = "MiB/s"; | ||||||
|  |     } else if (up_bps > KiB) { | ||||||
|  |         up_bps /= (float)KiB; | ||||||
|  |         up_bps_unit = "KiB/s"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (down_bps > MiB) { | ||||||
|  |         down_bps /= (float)MiB; | ||||||
|  |         down_bps_unit = "MiB/s"; | ||||||
|  |     } else if (down_bps > KiB) { | ||||||
|  |         down_bps /= (float)KiB; | ||||||
|  |         down_bps_unit = "KiB/s"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     snprintf(stb->network_info, sizeof(stb->network_info), | ||||||
|  |              " | [Up: %.1f%s (%.1f%s) | Down: %.1f%s (%.1f%s)]", up, up_unit, up_bps, up_bps_unit, | ||||||
|  |              down, down_unit, down_bps, down_bps_unit); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void prompt_onDraw(ToxWindow *self, Tox *m) | static void prompt_onDraw(ToxWindow *self, Tox *m) | ||||||
| { | { | ||||||
|     int x2; |     int x2; | ||||||
| @@ -464,6 +534,10 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) | |||||||
|         wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); |         wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (user_settings->show_network_info) { | ||||||
|  |         draw_network_info(m, statusbar); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     int y; |     int y; | ||||||
|     int x; |     int x; | ||||||
|     getyx(self->window, y, x); |     getyx(self->window, y, x); | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ static struct ui_strings { | |||||||
|     const char *show_typing_other; |     const char *show_typing_other; | ||||||
|     const char *show_welcome_msg; |     const char *show_welcome_msg; | ||||||
|     const char *show_connection_msg; |     const char *show_connection_msg; | ||||||
|     const char *show_group_connection_msg; |     const char *show_network_info; | ||||||
|     const char *nodeslist_update_freq; |     const char *nodeslist_update_freq; | ||||||
|     const char *autosave_freq; |     const char *autosave_freq; | ||||||
|  |  | ||||||
| @@ -71,8 +71,6 @@ static struct ui_strings { | |||||||
|     const char *line_quit; |     const char *line_quit; | ||||||
|     const char *line_alert; |     const char *line_alert; | ||||||
|     const char *line_normal; |     const char *line_normal; | ||||||
|     const char *line_special; |  | ||||||
|     const char *group_part_message; |  | ||||||
|  |  | ||||||
|     const char *mplex_away; |     const char *mplex_away; | ||||||
|     const char *mplex_away_note; |     const char *mplex_away_note; | ||||||
| @@ -100,19 +98,15 @@ static struct ui_strings { | |||||||
|     "show_typing_other", |     "show_typing_other", | ||||||
|     "show_welcome_msg", |     "show_welcome_msg", | ||||||
|     "show_connection_msg", |     "show_connection_msg", | ||||||
|     "show_group_connection_msg", |     "show_network_info", | ||||||
|     "nodeslist_update_freq", |     "nodeslist_update_freq", | ||||||
|     "autosave_freq", |     "autosave_freq", | ||||||
|     "line_join", |     "line_join", | ||||||
|     "line_quit", |     "line_quit", | ||||||
|     "line_alert", |     "line_alert", | ||||||
|     "line_normal", |     "line_normal", | ||||||
|     "line_special", |  | ||||||
|     "group_part_message", |  | ||||||
|  |  | ||||||
|     "mplex_away", |     "mplex_away", | ||||||
|     "mplex_away_note", |     "mplex_away_note", | ||||||
|  |  | ||||||
|     "color_bar_bg", |     "color_bar_bg", | ||||||
|     "color_bar_fg", |     "color_bar_fg", | ||||||
|     "color_bar_accent", |     "color_bar_accent", | ||||||
| @@ -138,15 +132,14 @@ static void ui_defaults(struct user_settings *settings) | |||||||
|     settings->show_typing_other = SHOW_TYPING_ON; |     settings->show_typing_other = SHOW_TYPING_ON; | ||||||
|     settings->show_welcome_msg = SHOW_WELCOME_MSG_ON; |     settings->show_welcome_msg = SHOW_WELCOME_MSG_ON; | ||||||
|     settings->show_connection_msg = SHOW_CONNECTION_MSG_ON; |     settings->show_connection_msg = SHOW_CONNECTION_MSG_ON; | ||||||
|     settings->show_group_connection_msg = SHOW_GROUP_CONNECTION_MSG_ON; |     settings->show_network_info = SHOW_NETWORK_INFO_OFF; | ||||||
|     settings->nodeslist_update_freq = 1; |     settings->nodeslist_update_freq = 7; | ||||||
|     settings->autosave_freq = 600; |     settings->autosave_freq = 600; | ||||||
|  |  | ||||||
|     snprintf(settings->line_join, LINE_HINT_MAX + 1, "%s", LINE_JOIN); |     snprintf(settings->line_join, LINE_HINT_MAX + 1, "%s", LINE_JOIN); | ||||||
|     snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT); |     snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT); | ||||||
|     snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT); |     snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT); | ||||||
|     snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL); |     snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL); | ||||||
|     snprintf(settings->line_special, LINE_HINT_MAX + 1, "%s", LINE_SPECIAL); |  | ||||||
|  |  | ||||||
|     settings->mplex_away = MPLEX_ON; |     settings->mplex_away = MPLEX_ON; | ||||||
|     snprintf(settings->mplex_away_note, sizeof(settings->mplex_away_note), "%s", MPLEX_AWAY_NOTE); |     snprintf(settings->mplex_away_note, sizeof(settings->mplex_away_note), "%s", MPLEX_AWAY_NOTE); | ||||||
| @@ -408,7 +401,7 @@ int settings_load(struct user_settings *s, const char *patharg) | |||||||
|         config_setting_lookup_bool(setting, ui_strings.show_typing_other, &s->show_typing_other); |         config_setting_lookup_bool(setting, ui_strings.show_typing_other, &s->show_typing_other); | ||||||
|         config_setting_lookup_bool(setting, ui_strings.show_welcome_msg, &s->show_welcome_msg); |         config_setting_lookup_bool(setting, ui_strings.show_welcome_msg, &s->show_welcome_msg); | ||||||
|         config_setting_lookup_bool(setting, ui_strings.show_connection_msg, &s->show_connection_msg); |         config_setting_lookup_bool(setting, ui_strings.show_connection_msg, &s->show_connection_msg); | ||||||
|         config_setting_lookup_bool(setting, ui_strings.show_group_connection_msg, &s->show_group_connection_msg); |         config_setting_lookup_bool(setting, ui_strings.show_network_info, &s->show_network_info); | ||||||
|  |  | ||||||
|         config_setting_lookup_int(setting, ui_strings.history_size, &s->history_size); |         config_setting_lookup_int(setting, ui_strings.history_size, &s->history_size); | ||||||
|         config_setting_lookup_int(setting, ui_strings.notification_timeout, &s->notification_timeout); |         config_setting_lookup_int(setting, ui_strings.notification_timeout, &s->notification_timeout); | ||||||
| @@ -431,19 +424,11 @@ int settings_load(struct user_settings *s, const char *patharg) | |||||||
|             snprintf(s->line_normal, sizeof(s->line_normal), "%s", str); |             snprintf(s->line_normal, sizeof(s->line_normal), "%s", str); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (config_setting_lookup_string(setting, ui_strings.line_special, &str)) { |  | ||||||
|             snprintf(s->line_special, sizeof(s->line_special), "%s", str); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         config_setting_lookup_bool(setting, ui_strings.mplex_away, &s->mplex_away); |         config_setting_lookup_bool(setting, ui_strings.mplex_away, &s->mplex_away); | ||||||
|  |  | ||||||
|         if (config_setting_lookup_string(setting, ui_strings.mplex_away_note, &str)) { |         if (config_setting_lookup_string(setting, ui_strings.mplex_away_note, &str)) { | ||||||
|             snprintf(s->mplex_away_note, sizeof(s->mplex_away_note), "%s", str); |             snprintf(s->mplex_away_note, sizeof(s->mplex_away_note), "%s", str); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (config_setting_lookup_string(setting, ui_strings.group_part_message, &str)) { |  | ||||||
|             snprintf(s->group_part_message, sizeof(s->group_part_message), "%s", str); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* paths */ |     /* paths */ | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ struct user_settings { | |||||||
|     int show_typing_other; /* boolean */ |     int show_typing_other; /* boolean */ | ||||||
|     int show_welcome_msg;  /* boolean */ |     int show_welcome_msg;  /* boolean */ | ||||||
|     int show_connection_msg;  /* boolean */ |     int show_connection_msg;  /* boolean */ | ||||||
|     int show_group_connection_msg;  /* boolean */ |     int show_network_info; /* boolean */ | ||||||
|     int nodeslist_update_freq;  /* int (<= 0 to disable updates) */ |     int nodeslist_update_freq;  /* int (<= 0 to disable updates) */ | ||||||
|     int autosave_freq; /* int (<= 0 to disable autosave) */ |     int autosave_freq; /* int (<= 0 to disable autosave) */ | ||||||
|  |  | ||||||
| @@ -62,7 +62,6 @@ struct user_settings { | |||||||
|     char line_quit[LINE_HINT_MAX + 1]; |     char line_quit[LINE_HINT_MAX + 1]; | ||||||
|     char line_alert[LINE_HINT_MAX + 1]; |     char line_alert[LINE_HINT_MAX + 1]; | ||||||
|     char line_normal[LINE_HINT_MAX + 1]; |     char line_normal[LINE_HINT_MAX + 1]; | ||||||
|     char line_special[LINE_HINT_MAX + 1]; |  | ||||||
|  |  | ||||||
|     char download_path[PATH_MAX]; |     char download_path[PATH_MAX]; | ||||||
|     char chatlogs_path[PATH_MAX]; |     char chatlogs_path[PATH_MAX]; | ||||||
| @@ -87,7 +86,6 @@ struct user_settings { | |||||||
|  |  | ||||||
|     int mplex_away; /* boolean (1 for reaction to terminal attach/detach) */ |     int mplex_away; /* boolean (1 for reaction to terminal attach/detach) */ | ||||||
|     char mplex_away_note [TOX_MAX_STATUS_MESSAGE_LENGTH]; |     char mplex_away_note [TOX_MAX_STATUS_MESSAGE_LENGTH]; | ||||||
|     char group_part_message[TOX_GROUP_MAX_PART_LENGTH]; |  | ||||||
|  |  | ||||||
| #ifdef AUDIO | #ifdef AUDIO | ||||||
|     int audio_in_dev; |     int audio_in_dev; | ||||||
| @@ -123,8 +121,8 @@ enum settings_values { | |||||||
|     SHOW_CONNECTION_MSG_OFF = 0, |     SHOW_CONNECTION_MSG_OFF = 0, | ||||||
|     SHOW_CONNECTION_MSG_ON = 1, |     SHOW_CONNECTION_MSG_ON = 1, | ||||||
|  |  | ||||||
|     SHOW_GROUP_CONNECTION_MSG_OFF = 0, |     SHOW_NETWORK_INFO_OFF = 0, | ||||||
|     SHOW_GROUP_CONNECTION_MSG_ON = 1, |     SHOW_NETWORK_INFO_ON = 1, | ||||||
|  |  | ||||||
|     DFLT_HST_SIZE = 700, |     DFLT_HST_SIZE = 700, | ||||||
|  |  | ||||||
| @@ -136,7 +134,6 @@ enum settings_values { | |||||||
| #define LINE_QUIT    "<--" | #define LINE_QUIT    "<--" | ||||||
| #define LINE_ALERT   "-!-" | #define LINE_ALERT   "-!-" | ||||||
| #define LINE_NORMAL  "-" | #define LINE_NORMAL  "-" | ||||||
| #define LINE_SPECIAL ">" |  | ||||||
| #define TIMESTAMP_DEFAULT      "%H:%M" | #define TIMESTAMP_DEFAULT      "%H:%M" | ||||||
| #define LOG_TIMESTAMP_DEFAULT  "%Y/%m/%d [%H:%M:%S]" | #define LOG_TIMESTAMP_DEFAULT  "%Y/%m/%d [%H:%M:%S]" | ||||||
| #define MPLEX_AWAY_NOTE "Away from keyboard, be back soon!" | #define MPLEX_AWAY_NOTE "Away from keyboard, be back soon!" | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								src/toxic.c
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								src/toxic.c
									
									
									
									
									
								
							| @@ -37,7 +37,6 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||||
| #include <sys/time.h> |  | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
| #include <termios.h> | #include <termios.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
| @@ -54,12 +53,12 @@ | |||||||
| #include "execute.h" | #include "execute.h" | ||||||
| #include "file_transfers.h" | #include "file_transfers.h" | ||||||
| #include "friendlist.h" | #include "friendlist.h" | ||||||
| #include "groupchats.h" |  | ||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "log.h" | #include "log.h" | ||||||
| #include "message_queue.h" | #include "message_queue.h" | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| #include "name_lookup.h" | #include "name_lookup.h" | ||||||
|  | #include "netprof.h" | ||||||
| #include "notify.h" | #include "notify.h" | ||||||
| #include "prompt.h" | #include "prompt.h" | ||||||
| #include "settings.h" | #include "settings.h" | ||||||
| @@ -145,6 +144,22 @@ static void catch_SIGSEGV(int sig) | |||||||
|     exit(EXIT_FAILURE); |     exit(EXIT_FAILURE); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void cb_toxcore_logger(Tox *m, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func, | ||||||
|  |                        const char *message, void *user_data) | ||||||
|  | { | ||||||
|  |     UNUSED_VAR(user_data); | ||||||
|  |     UNUSED_VAR(file); | ||||||
|  |     UNUSED_VAR(m); | ||||||
|  |  | ||||||
|  |     if (user_data) { | ||||||
|  |         FILE *fp = (FILE *)user_data; | ||||||
|  |         fprintf(fp, "[%d] %u:%s() - %s\n", level, line, func, message); | ||||||
|  |         fflush(fp); | ||||||
|  |     } else { | ||||||
|  |         fprintf(stderr, "[%d] %u:%s() - %s\n", level, line, func, message); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| static void flag_window_resize(int sig) | static void flag_window_resize(int sig) | ||||||
| { | { | ||||||
|     UNUSED_VAR(sig); |     UNUSED_VAR(sig); | ||||||
| @@ -179,6 +194,10 @@ void free_global_data(void) | |||||||
|  |  | ||||||
| void exit_toxic_success(Tox *m) | void exit_toxic_success(Tox *m) | ||||||
| { | { | ||||||
|  |     if (arg_opts.netprof_log_dump) { | ||||||
|  |         netprof_log_dump(m, arg_opts.netprof_fp, get_unix_time() - arg_opts.netprof_start_time); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     store_data(m, DATA_FILE); |     store_data(m, DATA_FILE); | ||||||
|  |  | ||||||
|     user_password = (struct user_password) { |     user_password = (struct user_password) { | ||||||
| @@ -209,6 +228,11 @@ void exit_toxic_success(Tox *m) | |||||||
|         arg_opts.log_fp = NULL; |         arg_opts.log_fp = NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (arg_opts.netprof_fp != NULL) { | ||||||
|  |         fclose(arg_opts.netprof_fp); | ||||||
|  |         arg_opts.netprof_fp = NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     endwin(); |     endwin(); | ||||||
|     curl_global_cleanup(); |     curl_global_cleanup(); | ||||||
|  |  | ||||||
| @@ -231,54 +255,6 @@ void exit_toxic_err(const char *errmsg, int errcode) | |||||||
|     exit(EXIT_FAILURE); |     exit(EXIT_FAILURE); | ||||||
| } | } | ||||||
|  |  | ||||||
| static const char *tox_log_level_show(Tox_Log_Level level) |  | ||||||
| { |  | ||||||
|     switch (level) { |  | ||||||
|         case TOX_LOG_LEVEL_TRACE: |  | ||||||
|             return "TRACE"; |  | ||||||
|  |  | ||||||
|         case TOX_LOG_LEVEL_DEBUG: |  | ||||||
|             return "DEBUG"; |  | ||||||
|  |  | ||||||
|         case TOX_LOG_LEVEL_INFO: |  | ||||||
|             return "INFO"; |  | ||||||
|  |  | ||||||
|         case TOX_LOG_LEVEL_WARNING: |  | ||||||
|             return "WARNING"; |  | ||||||
|  |  | ||||||
|         case TOX_LOG_LEVEL_ERROR: |  | ||||||
|             return "ERROR"; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return "<invalid>"; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cb_toxcore_logger(Tox *m, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func, |  | ||||||
|                        const char *message, void *user_data) |  | ||||||
| { |  | ||||||
|     UNUSED_VAR(m); |  | ||||||
|  |  | ||||||
|     if (level == TOX_LOG_LEVEL_TRACE) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     FILE *fp = (FILE *)user_data; |  | ||||||
|  |  | ||||||
|     if (!fp) { |  | ||||||
|         fp = stderr; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     struct timeval tv; |  | ||||||
|     gettimeofday(&tv, NULL); |  | ||||||
|     struct tm tmp; |  | ||||||
|     gmtime_r(&tv.tv_sec, &tmp); |  | ||||||
|     char timestamp[200]; |  | ||||||
|     strftime(timestamp, sizeof(timestamp), "%F %T", &tmp); |  | ||||||
|  |  | ||||||
|     fprintf(fp, "%c %s.%06ld %s:%u(%s) - %s\n", tox_log_level_show(level)[0], timestamp, tv.tv_usec, file, line, func, message); |  | ||||||
|     fflush(fp); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* Sets ncurses refresh rate. Lower values make it refresh more often. */ | /* Sets ncurses refresh rate. Lower values make it refresh more often. */ | ||||||
| void set_window_refresh_rate(size_t refresh_rate) | void set_window_refresh_rate(size_t refresh_rate) | ||||||
| { | { | ||||||
| @@ -506,17 +482,6 @@ static void load_friendlist(Tox *m) | |||||||
|     sort_friendlist_index(); |     sort_friendlist_index(); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void load_groups(Tox *m) |  | ||||||
| { |  | ||||||
|     size_t numgroups = tox_group_get_number_groups(m); |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < numgroups; ++i) { |  | ||||||
|         if (init_groupchat_win(m, i, NULL, 0, Group_Join_Type_Load) != 0) { |  | ||||||
|             tox_group_leave(m, i, NULL, 0, NULL); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void load_conferences(Tox *m) | static void load_conferences(Tox *m) | ||||||
| { | { | ||||||
|     size_t num_chats = tox_conference_get_chatlist_size(m); |     size_t num_chats = tox_conference_get_chatlist_size(m); | ||||||
| @@ -860,22 +825,6 @@ static void init_tox_callbacks(Tox *m) | |||||||
|     tox_callback_file_recv_control(m, on_file_recv_control); |     tox_callback_file_recv_control(m, on_file_recv_control); | ||||||
|     tox_callback_file_recv_chunk(m, on_file_recv_chunk); |     tox_callback_file_recv_chunk(m, on_file_recv_chunk); | ||||||
|     tox_callback_friend_lossless_packet(m, on_lossless_custom_packet); |     tox_callback_friend_lossless_packet(m, on_lossless_custom_packet); | ||||||
|     tox_callback_group_invite(m, on_group_invite); |  | ||||||
|     tox_callback_group_message(m, on_group_message); |  | ||||||
|     tox_callback_group_private_message(m, on_group_private_message); |  | ||||||
|     tox_callback_group_peer_status(m, on_group_status_change); |  | ||||||
|     tox_callback_group_peer_join(m, on_group_peer_join); |  | ||||||
|     tox_callback_group_peer_exit(m, on_group_peer_exit); |  | ||||||
|     tox_callback_group_peer_name(m, on_group_nick_change); |  | ||||||
|     tox_callback_group_topic(m, on_group_topic_change); |  | ||||||
|     tox_callback_group_peer_limit(m, on_group_peer_limit); |  | ||||||
|     tox_callback_group_privacy_state(m, on_group_privacy_state); |  | ||||||
|     tox_callback_group_topic_lock(m, on_group_topic_lock); |  | ||||||
|     tox_callback_group_password(m, on_group_password); |  | ||||||
|     tox_callback_group_self_join(m, on_group_self_join); |  | ||||||
|     tox_callback_group_join_fail(m, on_group_rejected); |  | ||||||
|     tox_callback_group_moderation(m, on_group_moderation); |  | ||||||
|     tox_callback_group_voice_state(m, on_group_voice_state); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void init_tox_options(struct Tox_Options *tox_opts) | static void init_tox_options(struct Tox_Options *tox_opts) | ||||||
| @@ -1260,6 +1209,7 @@ static void print_usage(void) | |||||||
|     fprintf(stderr, "  -p, --SOCKS5-proxy       Use SOCKS5 proxy: Requires [IP] [port]\n"); |     fprintf(stderr, "  -p, --SOCKS5-proxy       Use SOCKS5 proxy: Requires [IP] [port]\n"); | ||||||
|     fprintf(stderr, "  -P, --HTTP-proxy         Use HTTP proxy: Requires [IP] [port]\n"); |     fprintf(stderr, "  -P, --HTTP-proxy         Use HTTP proxy: Requires [IP] [port]\n"); | ||||||
|     fprintf(stderr, "  -r, --namelist           Use specified name lookup server list\n"); |     fprintf(stderr, "  -r, --namelist           Use specified name lookup server list\n"); | ||||||
|  |     fprintf(stderr, "  -s, --netstats           Dump network statistic to log on exit: Requires [path]\n"); | ||||||
|     fprintf(stderr, "  -t, --force-tcp          Force toxic to use a TCP connection (use with proxies)\n"); |     fprintf(stderr, "  -t, --force-tcp          Force toxic to use a TCP connection (use with proxies)\n"); | ||||||
|     fprintf(stderr, "  -T, --tcp-server         Act as a TCP relay server: Requires [port]\n"); |     fprintf(stderr, "  -T, --tcp-server         Act as a TCP relay server: Requires [port]\n"); | ||||||
|     fprintf(stderr, "  -u, --unencrypt-data     Unencrypt an encrypted data file\n"); |     fprintf(stderr, "  -u, --unencrypt-data     Unencrypt an encrypted data file\n"); | ||||||
| @@ -1299,6 +1249,7 @@ static void parse_args(int argc, char *argv[]) | |||||||
|         {"help", no_argument, 0, 'h'}, |         {"help", no_argument, 0, 'h'}, | ||||||
|         {"noconnect", no_argument, 0, 'o'}, |         {"noconnect", no_argument, 0, 'o'}, | ||||||
|         {"namelist", required_argument, 0, 'r'}, |         {"namelist", required_argument, 0, 'r'}, | ||||||
|  |         {"netstats", required_argument, 0, 's'}, | ||||||
|         {"force-tcp", no_argument, 0, 't'}, |         {"force-tcp", no_argument, 0, 't'}, | ||||||
|         {"tcp-server", required_argument, 0, 'T'}, |         {"tcp-server", required_argument, 0, 'T'}, | ||||||
|         {"SOCKS5-proxy", required_argument, 0, 'p'}, |         {"SOCKS5-proxy", required_argument, 0, 'p'}, | ||||||
| @@ -1308,7 +1259,7 @@ static void parse_args(int argc, char *argv[]) | |||||||
|         {NULL, no_argument, NULL, 0}, |         {NULL, no_argument, NULL, 0}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     const char *opts_str = "4bdehLotuxvc:f:l:n:r:p:P:T:"; |     const char *opts_str = "4bdehLotuxvc:f:l:n:r:s:p:P:T:"; | ||||||
|     int opt = 0; |     int opt = 0; | ||||||
|     int indexptr = 0; |     int indexptr = 0; | ||||||
|  |  | ||||||
| @@ -1504,6 +1455,25 @@ static void parse_args(int argc, char *argv[]) | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             case 's': { | ||||||
|  |                 if (optarg == NULL) { | ||||||
|  |                     queue_init_message("Invalid argument for option: %d", opt); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 arg_opts.netprof_fp = fopen(optarg, "w"); | ||||||
|  |  | ||||||
|  |                 if (arg_opts.netprof_fp != NULL) { | ||||||
|  |                     queue_init_message("Network profile logging enabled. Logging to file: '%s'", optarg); | ||||||
|  |                     arg_opts.netprof_log_dump = true; | ||||||
|  |                     arg_opts.netprof_start_time = time(NULL); | ||||||
|  |                 } else { | ||||||
|  |                     queue_init_message("Failed to open file '%s' for network profile logging.", optarg); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             case 'u': { |             case 'u': { | ||||||
|                 arg_opts.unencrypt_data = 1; |                 arg_opts.unencrypt_data = 1; | ||||||
|                 break; |                 break; | ||||||
| @@ -1645,7 +1615,6 @@ int main(int argc, char **argv) | |||||||
|  |  | ||||||
|     prompt = init_windows(m); |     prompt = init_windows(m); | ||||||
|     prompt_init_statusbar(prompt, m, !datafile_exists); |     prompt_init_statusbar(prompt, m, !datafile_exists); | ||||||
|     load_groups(m); |  | ||||||
|     load_conferences(m); |     load_conferences(m); | ||||||
|     set_active_window_index(0); |     set_active_window_index(0); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								src/toxic.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/toxic.h
									
									
									
									
									
								
							| @@ -148,32 +148,6 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k | |||||||
| void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata); | void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata); | ||||||
| void on_friend_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata); | void on_friend_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata); | ||||||
| void on_lossless_custom_packet(Tox *m, uint32_t friendnumber, const uint8_t *data, size_t length, void *userdata); | void on_lossless_custom_packet(Tox *m, uint32_t friendnumber, const uint8_t *data, size_t length, void *userdata); | ||||||
| void on_group_invite(Tox *m, uint32_t friendnumber, const uint8_t *invite_data, size_t length, |  | ||||||
|                      const uint8_t *group_name, |  | ||||||
|                      size_t group_name_length, void *userdata); |  | ||||||
| void on_group_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type, |  | ||||||
|                       const uint8_t *message, size_t length, uint32_t message_id, void *userdata); |  | ||||||
| void on_group_private_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type, |  | ||||||
|                               const uint8_t *message, size_t length, |  | ||||||
|                               void *userdata); |  | ||||||
| void on_group_peer_join(Tox *m, uint32_t groupnumber, uint32_t peernumber, void *userdata); |  | ||||||
| void on_group_peer_exit(Tox *m, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type, |  | ||||||
|                         const uint8_t *nick, |  | ||||||
|                         size_t nick_len, const uint8_t *partmsg, size_t length, void *userdata); |  | ||||||
| void on_group_topic_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *topic, size_t length, |  | ||||||
|                            void *userdata); |  | ||||||
| void on_group_peer_limit(Tox *m, uint32_t groupnumber, uint32_t peer_limit, void *userdata); |  | ||||||
| void on_group_privacy_state(Tox *m, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state, void *userdata); |  | ||||||
| void on_group_topic_lock(Tox *m, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *userdata); |  | ||||||
| void on_group_password(Tox *m, uint32_t groupnumber, const uint8_t *password, size_t length, void *userdata); |  | ||||||
| void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *newname, size_t length, |  | ||||||
|                           void *userdata); |  | ||||||
| void on_group_status_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_USER_STATUS status, void *userdata); |  | ||||||
| void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata); |  | ||||||
| void on_group_rejected(Tox *m, uint32_t groupnumber, Tox_Group_Join_Fail type, void *userdata); |  | ||||||
| void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peernum, uint32_t target_peernum, |  | ||||||
|                          Tox_Group_Mod_Event type, void *userdata); |  | ||||||
| void on_group_voice_state(Tox *m, uint32_t groupnumber, Tox_Group_Voice_State voice_state, void *userdata); |  | ||||||
|  |  | ||||||
| extern char *DATA_FILE; | extern char *DATA_FILE; | ||||||
| extern char *BLOCK_FILE; | extern char *BLOCK_FILE; | ||||||
|   | |||||||
							
								
								
									
										197
									
								
								src/windows.c
									
									
									
									
									
								
							
							
						
						
									
										197
									
								
								src/windows.c
									
									
									
									
									
								
							| @@ -30,7 +30,6 @@ | |||||||
| #include "conference.h" | #include "conference.h" | ||||||
| #include "file_transfers.h" | #include "file_transfers.h" | ||||||
| #include "friendlist.h" | #include "friendlist.h" | ||||||
| #include "groupchats.h" |  | ||||||
| #include "line_info.h" | #include "line_info.h" | ||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| #include "prompt.h" | #include "prompt.h" | ||||||
| @@ -380,192 +379,6 @@ void on_lossless_custom_packet(Tox *m, uint32_t friendnumber, const uint8_t *dat | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void on_group_invite(Tox *m, uint32_t friendnumber, const uint8_t *invite_data, size_t length, |  | ||||||
|                      const uint8_t *group_name, |  | ||||||
|                      size_t group_name_length, void *userdata) |  | ||||||
| { |  | ||||||
|     char gname[MAX_STR_SIZE + 1]; |  | ||||||
|     group_name_length = copy_tox_str(gname, sizeof(gname), (const char *) group_name, group_name_length); |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupInvite != NULL) { |  | ||||||
|             windows[i]->onGroupInvite(windows[i], m, friendnumber, (char *) invite_data, length, gname, group_name_length); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_message(Tox *m, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, |  | ||||||
|                       const uint8_t *message, size_t length, uint32_t message_id, void *userdata) |  | ||||||
| { |  | ||||||
|     UNUSED_VAR(message_id); |  | ||||||
|  |  | ||||||
|     char msg[MAX_STR_SIZE + 1]; |  | ||||||
|     length = copy_tox_str(msg, sizeof(msg), (const char *) message, length); |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupMessage != NULL) { |  | ||||||
|             windows[i]->onGroupMessage(windows[i], m, groupnumber, peer_id, type, msg, length); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_private_message(Tox *m, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type, |  | ||||||
|                               const uint8_t *message, |  | ||||||
|                               size_t length, void *userdata) |  | ||||||
| { |  | ||||||
|     char msg[MAX_STR_SIZE + 1]; |  | ||||||
|     length = copy_tox_str(msg, sizeof(msg), (const char *) message, length); |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupPrivateMessage != NULL) { |  | ||||||
|             windows[i]->onGroupPrivateMessage(windows[i], m, groupnumber, peer_id, msg, length); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_status_change(Tox *m, uint32_t groupnumber, uint32_t peer_id, TOX_USER_STATUS status, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupStatusChange != NULL) { |  | ||||||
|             windows[i]->onGroupStatusChange(windows[i], m, groupnumber, peer_id, status); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     flag_interface_refresh(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_peer_join(Tox *m, uint32_t groupnumber, uint32_t peer_id, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupPeerJoin != NULL) { |  | ||||||
|             windows[i]->onGroupPeerJoin(windows[i], m, groupnumber, peer_id); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     flag_interface_refresh(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_peer_exit(Tox *m, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type, |  | ||||||
|                         const uint8_t *nick, |  | ||||||
|                         size_t nick_len, const uint8_t *part_message, size_t length, void *userdata) |  | ||||||
| { |  | ||||||
|     char toxic_nick[TOXIC_MAX_NAME_LENGTH + 1]; |  | ||||||
|     nick_len = copy_tox_str(toxic_nick, sizeof(toxic_nick), (const char *) nick, nick_len); |  | ||||||
|  |  | ||||||
|     char buf[MAX_STR_SIZE + 1] = {0}; |  | ||||||
|     size_t buf_len = 0; |  | ||||||
|  |  | ||||||
|     if (part_message) { |  | ||||||
|         buf_len = copy_tox_str(buf, sizeof(buf), (const char *) part_message, length); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupPeerExit != NULL) { |  | ||||||
|             windows[i]->onGroupPeerExit(windows[i], m, groupnumber, peer_id, exit_type, toxic_nick, nick_len, buf, buf_len); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_topic_change(Tox *m, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic, size_t length, |  | ||||||
|                            void *userdata) |  | ||||||
| { |  | ||||||
|     char data[MAX_STR_SIZE + 1]; |  | ||||||
|     length = copy_tox_str(data, sizeof(data), (const char *) topic, length); |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupTopicChange != NULL) { |  | ||||||
|             windows[i]->onGroupTopicChange(windows[i], m, groupnumber, peer_id, data, length); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_peer_limit(Tox *m, uint32_t groupnumber, uint32_t peer_limit, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupPeerLimit != NULL) { |  | ||||||
|             windows[i]->onGroupPeerLimit(windows[i], m, groupnumber, peer_limit); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_privacy_state(Tox *m, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupPrivacyState != NULL) { |  | ||||||
|             windows[i]->onGroupPrivacyState(windows[i], m, groupnumber, privacy_state); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_topic_lock(Tox *m, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupTopicLock != NULL) { |  | ||||||
|             windows[i]->onGroupTopicLock(windows[i], m, groupnumber, topic_lock); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_password(Tox *m, uint32_t groupnumber, const uint8_t *password, size_t length, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupPassword != NULL) { |  | ||||||
|             windows[i]->onGroupPassword(windows[i], m, groupnumber, (char *) password, length); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peer_id, const uint8_t *newname, size_t length, |  | ||||||
|                           void *userdata) |  | ||||||
| { |  | ||||||
|     char name[TOXIC_MAX_NAME_LENGTH + 1]; |  | ||||||
|     length = copy_tox_str(name, sizeof(name), (const char *) newname, length); |  | ||||||
|     filter_str(name, length); |  | ||||||
|  |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupNickChange != NULL) { |  | ||||||
|             windows[i]->onGroupNickChange(windows[i], m, groupnumber, peer_id, name, length); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupSelfJoin != NULL) { |  | ||||||
|             windows[i]->onGroupSelfJoin(windows[i], m, groupnumber); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_rejected(Tox *m, uint32_t groupnumber, Tox_Group_Join_Fail type, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupRejected != NULL) { |  | ||||||
|             windows[i]->onGroupRejected(windows[i], m, groupnumber, type); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peer_id, uint32_t target_peer_id, |  | ||||||
|                          Tox_Group_Mod_Event type, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupModeration != NULL) { |  | ||||||
|             windows[i]->onGroupModeration(windows[i], m, groupnumber, source_peer_id, target_peer_id, type); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void on_group_voice_state(Tox *m, uint32_t groupnumber, Tox_Group_Voice_State voice_state, void *userdata) |  | ||||||
| { |  | ||||||
|     for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) { |  | ||||||
|         if (windows[i] != NULL && windows[i]->onGroupVoiceState != NULL) { |  | ||||||
|             windows[i]->onGroupVoiceState(windows[i], m, groupnumber, voice_state); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* CALLBACKS END */ | /* CALLBACKS END */ | ||||||
|  |  | ||||||
| int add_window(Tox *m, ToxWindow *w) | int add_window(Tox *m, ToxWindow *w) | ||||||
| @@ -736,7 +549,7 @@ void on_window_resize(void) | |||||||
|             wclear(w->help->win); |             wclear(w->help->win); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (w->type == WINDOW_TYPE_CONFERENCE || w->type == WINDOW_TYPE_GROUPCHAT) { |         if (w->type == WINDOW_TYPE_CONFERENCE) { | ||||||
|             delwin(w->chatwin->sidebar); |             delwin(w->chatwin->sidebar); | ||||||
|             w->chatwin->sidebar = NULL; |             w->chatwin->sidebar = NULL; | ||||||
|         } else { |         } else { | ||||||
| @@ -764,7 +577,7 @@ void on_window_resize(void) | |||||||
|         } else { |         } else { | ||||||
|             w->chatwin->history =  subwin(w->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0); |             w->chatwin->history =  subwin(w->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0); | ||||||
|  |  | ||||||
|             if (!(w->type == WINDOW_TYPE_CONFERENCE || w->type == WINDOW_TYPE_GROUPCHAT)) { |             if (w->type != WINDOW_TYPE_CONFERENCE) { | ||||||
|                 w->stb->topline = subwin(w->window, TOP_BAR_HEIGHT, x2, 0, 0); |                 w->stb->topline = subwin(w->window, TOP_BAR_HEIGHT, x2, 0, 0); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -1163,12 +976,6 @@ void kill_all_windows(Tox *m) | |||||||
|  |  | ||||||
| #endif // GAMES | #endif // GAMES | ||||||
|  |  | ||||||
|             case WINDOW_TYPE_GROUPCHAT: { |  | ||||||
|                 exit_groupchat(w, m, w->num, user_settings->group_part_message, |  | ||||||
|                                strlen(user_settings->group_part_message)); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             default: { |             default: { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -87,7 +87,6 @@ typedef enum { | |||||||
|     WINDOW_TYPE_PROMPT, |     WINDOW_TYPE_PROMPT, | ||||||
|     WINDOW_TYPE_CHAT, |     WINDOW_TYPE_CHAT, | ||||||
|     WINDOW_TYPE_CONFERENCE, |     WINDOW_TYPE_CONFERENCE, | ||||||
|     WINDOW_TYPE_GROUPCHAT, |  | ||||||
|     WINDOW_TYPE_FRIEND_LIST, |     WINDOW_TYPE_FRIEND_LIST, | ||||||
|  |  | ||||||
| #ifdef GAMES | #ifdef GAMES | ||||||
| @@ -143,6 +142,10 @@ struct arg_opts { | |||||||
|     bool logging; |     bool logging; | ||||||
|     FILE *log_fp; |     FILE *log_fp; | ||||||
|  |  | ||||||
|  |     bool   netprof_log_dump; | ||||||
|  |     time_t netprof_start_time; | ||||||
|  |     FILE   *netprof_fp; | ||||||
|  |  | ||||||
|     char proxy_address[256]; |     char proxy_address[256]; | ||||||
|     uint8_t proxy_type; |     uint8_t proxy_type; | ||||||
|     uint16_t proxy_port; |     uint16_t proxy_port; | ||||||
| @@ -193,24 +196,6 @@ struct ToxWindow { | |||||||
|     void(*onGameData)(ToxWindow *, Tox *, uint32_t, const uint8_t *, size_t); |     void(*onGameData)(ToxWindow *, Tox *, uint32_t, const uint8_t *, size_t); | ||||||
| #endif // GAMES | #endif // GAMES | ||||||
|  |  | ||||||
|     void(*onGroupInvite)(ToxWindow *, Tox *, uint32_t, const char *, size_t, const char *, size_t); |  | ||||||
|     void(*onGroupMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_MESSAGE_TYPE, const char *, size_t); |  | ||||||
|     void(*onGroupPrivateMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); |  | ||||||
|     void(*onGroupPeerJoin)(ToxWindow *, Tox *, uint32_t, uint32_t); |  | ||||||
|     void(*onGroupPeerExit)(ToxWindow *, Tox *, uint32_t, uint32_t, Tox_Group_Exit_Type, const char *, size_t, const char *, |  | ||||||
|                            size_t); |  | ||||||
|     void(*onGroupNickChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); |  | ||||||
|     void(*onGroupStatusChange)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_USER_STATUS); |  | ||||||
|     void(*onGroupTopicChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t); |  | ||||||
|     void(*onGroupPeerLimit)(ToxWindow *, Tox *, uint32_t, uint32_t); |  | ||||||
|     void(*onGroupPrivacyState)(ToxWindow *, Tox *, uint32_t, Tox_Group_Privacy_State); |  | ||||||
|     void(*onGroupTopicLock)(ToxWindow *, Tox *, uint32_t, Tox_Group_Topic_Lock); |  | ||||||
|     void(*onGroupPassword)(ToxWindow *, Tox *, uint32_t, const char *, size_t); |  | ||||||
|     void(*onGroupSelfJoin)(ToxWindow *, Tox *, uint32_t); |  | ||||||
|     void(*onGroupRejected)(ToxWindow *, Tox *, uint32_t, Tox_Group_Join_Fail); |  | ||||||
|     void(*onGroupModeration)(ToxWindow *, Tox *, uint32_t, uint32_t, uint32_t, Tox_Group_Mod_Event); |  | ||||||
|     void(*onGroupVoiceState)(ToxWindow *, Tox *, uint32_t, Tox_Group_Voice_State); |  | ||||||
|  |  | ||||||
| #ifdef AUDIO | #ifdef AUDIO | ||||||
|  |  | ||||||
|     void(*onInvite)(ToxWindow *, ToxAV *, uint32_t, int); |     void(*onInvite)(ToxWindow *, ToxAV *, uint32_t, int); | ||||||
| @@ -267,6 +252,12 @@ struct StatusBar { | |||||||
|     size_t nick_len; |     size_t nick_len; | ||||||
|     Tox_User_Status status; |     Tox_User_Status status; | ||||||
|     Tox_Connection connection; |     Tox_Connection connection; | ||||||
|  |  | ||||||
|  |     /* network info */ | ||||||
|  |     uint64_t up_bytes; | ||||||
|  |     uint64_t down_bytes; | ||||||
|  |     uint64_t time_last_refreshed; | ||||||
|  |     char network_info[MAX_STR_SIZE]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #ifdef AUDIO | #ifdef AUDIO | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user