static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, uint64_t filesize, uint8_t *filename, uint16_t filename_len) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); } else { tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); uint8_t nick[TOX_MAX_NAME_LENGTH]; int n_len = tox_get_name(m, num, nick); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); nick[n_len] = '\0'; uint8_t msg[MAX_STR_SIZE]; snprintf(msg, sizeof(msg), "* File transfer from %s failed: too many windows are open.", nick); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); alert_window(prompt, WINDOW_ALERT_1, true); } } }
/* puts friendnum's nick in buf, truncating at TOXIC_MAX_NAME_LENGTH if necessary. Returns nick len on success, -1 on failure */ int get_nick_truncate(Tox *m, char *buf, int friendnum) { int len = tox_get_name(m, friendnum, (uint8_t *) buf); len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); buf[len] = '\0'; return len; }
static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum , uint8_t status) { if (friendnum < 0) return; ChatContext *ctx = self->chatwin; uint8_t nick[TOX_MAX_NAME_LENGTH] = {0}; int n_len = tox_get_name(m, friendnum, nick); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); if (!nick[0]) { snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME); n_len = strlen(UNKNOWN_NAME); } nick[n_len] = '\0'; uint8_t timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); uint8_t *msg; if (status == 1) { msg = "has come online"; line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, GREEN); write_to_log(msg, nick, ctx->log, true); alert_window(self, WINDOW_ALERT_2, false); } else { msg = "has gone offline"; line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, RED); write_to_log(msg, nick, ctx->log, true); } }
static void friendlist_onAv(ToxWindow *self, ToxAv *av) { int id = toxav_get_peer_id(av, 0); id++; if ( id >= max_friends_index) return; Tox* m = toxav_get_tox(av); if (friends[id].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[id].chatwin = add_window(m, new_chat(m, friends[id].num)); } else { uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; tox_get_name(m, id, nick); nick[TOXIC_MAX_NAME_LENGTH] = '\0'; wprintw(prompt->window, "Audio action from: %s!\n", nick); prep_prompt_win(); wattron(prompt->window, COLOR_PAIR(RED)); wprintw(prompt->window, "* Warning: Too many windows are open.\n"); wattron(prompt->window, COLOR_PAIR(RED)); alert_window(prompt, WINDOW_ALERT_0, true); } } }
static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int num, uint8_t filenum, uint64_t filesize, uint8_t *filename, uint16_t filename_len) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); } else { tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; tox_get_name(m, num, nick); nick[TOXIC_MAX_NAME_LENGTH] = '\0'; prep_prompt_win(); wattron(prompt->window, COLOR_PAIR(RED)); wprintw(prompt->window, "* File transfer from %s failed: too many windows are open.\n", nick); wattron(prompt->window, COLOR_PAIR(RED)); alert_window(prompt, WINDOW_ALERT_1, true); } } }
static void chat_onMessage(ToxWindow *self, Tox *m, int num, uint8_t *msg, uint16_t len) { if (self->num != num) return; ChatContext *ctx = self->chatwin; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; tox_get_name(m, num, nick); nick[TOXIC_MAX_NAME_LENGTH] = '\0'; print_time(ctx->history); wattron(ctx->history, COLOR_PAIR(CYAN)); wprintw(ctx->history, "%s: ", nick); wattroff(ctx->history, COLOR_PAIR(CYAN)); if (msg[0] == '>') { wattron(ctx->history, COLOR_PAIR(GREEN)); wprintw(ctx->history, "%s\n", msg); wattroff(ctx->history, COLOR_PAIR(GREEN)); } else wprintw(ctx->history, "%s\n", msg); alert_window(self, WINDOW_ALERT_1, true); }
static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index) { int id = toxav_get_peer_id(av, call_index, 0); /*id++;*/ if ( id != ErrorInternal && id >= max_friends_index) return; Tox *m = toxav_get_tox(av); if (friends[id].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[id].chatwin = add_window(m, new_chat(m, friends[id].num)); } else { uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; int n_len = tox_get_name(m, id, nick); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); nick[n_len] = '\0'; uint8_t msg[MAX_STR_SIZE]; snprintf(msg, sizeof(msg), "Audio action from: %s!", nick); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); uint8_t *errmsg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED); alert_window(prompt, WINDOW_ALERT_0, true); } } }
static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *str, uint16_t len) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); } else { str[len] = '\0'; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; int n_len = tox_get_name(m, num, nick); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); nick[n_len] = '\0'; uint8_t timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt); line_info_add(prompt, timefrmt, nick, NULL, str, IN_MSG, 0, 0); uint8_t *msg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); alert_window(prompt, WINDOW_ALERT_1, true); } } }
int getfriendname_terminated(Tox *m, int friendnum, char *namebuf) { int res = tox_get_name(m, friendnum, (uint8_t *)namebuf); if (res >= 0) namebuf[res] = 0; else namebuf[0] = 0; return res; }
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int friendnumber, uint8_t *group_pub_key) { if (self->num != friendnumber) return; ChatContext *ctx = self->chatwin; uint8_t name[TOX_MAX_NAME_LENGTH] = {'\0'}; if (tox_get_name(m, friendnumber, name) == -1) return; wprintw(ctx->history, "%s has invited you to a group chat.\n", name); memcpy(friends[friendnumber].pending_groupchat, group_pub_key, TOX_CLIENT_ID_SIZE); wprintw(ctx->history, "Type \"/join\" to join the chat.\n"); alert_window(self, WINDOW_ALERT_2, true); }
void log_write(Tox *tox, int fid, const uint8_t *message, uint16_t length, _Bool self) { if(!logging_enabled) { return; } uint8_t path[512], *p; uint8_t name[TOX_MAX_NAME_LENGTH]; int namelen; uint8_t client_id[TOX_CLIENT_ID_SIZE]; FILE *file; p = path + datapath(path); tox_get_client_id(tox, fid, client_id); cid_to_string(p, client_id); p += TOX_CLIENT_ID_SIZE * 2; strcpy((char*)p, ".txt"); file = fopen((char*)path, "ab"); if(file) { time_t rawtime; time(&rawtime); if(self) { namelen = tox_get_self_name(tox, name); } else if((namelen = tox_get_name(tox, fid, name)) == -1) { //error reading name namelen = 0; } struct { uint64_t time; uint16_t namelen, length; uint8_t flags, zeroes[3]; } header = { .time = rawtime, .namelen = namelen, .length = length, .flags = self, }; fwrite(&header, sizeof(header), 1, file); fwrite(name, namelen, 1, file); fwrite(message, length, 1, file); fclose(file); } }
void log_write(Tox *tox, int fid, const uint8_t *message, uint16_t length, _Bool author, uint8_t msg_type) { if(!logging_enabled) { return; } uint8_t path[512], *p; uint8_t name[TOX_MAX_NAME_LENGTH]; int namelen; FILE *file; p = path + datapath(path); int len = log_file_name(p, sizeof(path) - (p - path), tox, fid); if (len == -1) return; p += len; file = fopen((char*)path, "ab"); if(file) { time_t rawtime; time(&rawtime); if(author) { namelen = tox_get_self_name(tox, name); } else if((namelen = tox_get_name(tox, fid, name)) == -1) { //error reading name namelen = 0; } LOG_FILE_MSG_HEADER header = { .time = rawtime, .namelen = namelen, .length = length, .flags = author, .msg_type = msg_type, }; fwrite(&header, sizeof(header), 1, file); fwrite(name, namelen, 1, file); fwrite(message, length, 1, file); fclose(file); } }
static void chat_onAction(ToxWindow *self, Tox *m, int num, uint8_t *action, uint16_t len) { if (self->num != num) return; ChatContext *ctx = self->chatwin; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; tox_get_name(m, num, nick); nick[TOXIC_MAX_NAME_LENGTH] = '\0'; print_time(ctx->history); wattron(ctx->history, COLOR_PAIR(YELLOW)); wprintw(ctx->history, "* %s %s\n", nick, action); wattroff(ctx->history, COLOR_PAIR(YELLOW)); alert_window(self, WINDOW_ALERT_1, true); }
static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int friendnum , uint8_t status) { if (friendnum < 0) return; PromptBuf *prt = self->promptbuf; prep_prompt_win(); uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; if (tox_get_name(m, friendnum, nick) == -1) return; if (!nick[0]) snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME); wprintw(self->window, "\n"); print_time(self->window); uint8_t *msg; if (status == 1) { msg = "has come online"; wattron(self->window, COLOR_PAIR(GREEN)); wattron(self->window, A_BOLD); wprintw(self->window, "* %s ", nick); wattroff(self->window, A_BOLD); wprintw(self->window, "%s\n", msg); wattroff(self->window, COLOR_PAIR(GREEN)); write_to_log(msg, nick, prt->log, true); alert_window(self, WINDOW_ALERT_2, false); } else { msg = "has gone offline"; wattron(self->window, COLOR_PAIR(RED)); wattron(self->window, A_BOLD); wprintw(self->window, "* %s ", nick); wattroff(self->window, A_BOLD); wprintw(self->window, "%s\n", msg); wattroff(self->window, COLOR_PAIR(RED)); write_to_log(msg, nick, prt->log, true); } }
ToxWindow new_chat(Tox *m, int friendnum) { ToxWindow ret; memset(&ret, 0, sizeof(ret)); ret.active = true; ret.onKey = &chat_onKey; ret.onDraw = &chat_onDraw; ret.onInit = &chat_onInit; ret.onMessage = &chat_onMessage; ret.onConnectionChange = &chat_onConnectionChange; ret.onGroupInvite = &chat_onGroupInvite; ret.onNickChange = &chat_onNickChange; ret.onStatusChange = &chat_onStatusChange; ret.onStatusMessageChange = &chat_onStatusMessageChange; ret.onAction = &chat_onAction; ret.onFileSendRequest = &chat_onFileSendRequest; ret.onFileControl = &chat_onFileControl; ret.onFileData = &chat_onFileData; uint8_t name[TOX_MAX_NAME_LENGTH] = {'\0'}; uint16_t len = tox_get_name(m, friendnum, name); memcpy(ret.name, name, len); ret.name[TOXIC_MAX_NAME_LENGTH] = '\0'; ChatContext *chatwin = calloc(1, sizeof(ChatContext)); StatusBar *stb = calloc(1, sizeof(StatusBar)); if (stb != NULL && chatwin != NULL) { ret.chatwin = chatwin; ret.stb = stb; } else { endwin(); fprintf(stderr, "calloc() failed. Aborting...\n"); exit(EXIT_FAILURE); } ret.num = friendnum; return ret; }
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int num, uint8_t *group_pub_key) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); } else { uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; tox_get_name(m, num, nick); nick[TOXIC_MAX_NAME_LENGTH] = '\0'; prep_prompt_win(); wattron(prompt->window, COLOR_PAIR(RED)); wprintw(prompt->window, "* Group chat invite from %s failed: too many windows are open.\n", nick); wattron(prompt->window, COLOR_PAIR(RED)); alert_window(prompt, WINDOW_ALERT_1, true); } } }
void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort) { if (max_friends_index < 0 || max_friends_index >= MAX_FRIENDS_NUM) return; int i; for (i = 0; i <= max_friends_index; ++i) { if (!friends[i].active) { friends[i].num = num; friends[i].active = true; friends[i].chatwin = -1; friends[i].online = false; friends[i].status = TOX_USERSTATUS_NONE; friends[i].namelength = tox_get_name(m, num, friends[i].name); friends[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON; tox_get_client_id(m, num, friends[i].pub_key); update_friend_last_online(i, tox_get_last_online(m, i)); if (friends[i].namelength == -1 || friends[i].name[0] == '\0') { strcpy(friends[i].name, (uint8_t *) UNKNOWN_NAME); friends[i].namelength = strlen(UNKNOWN_NAME); } else { /* Enforce toxic's maximum name length */ friends[i].namelength = MIN(friends[i].namelength, TOXIC_MAX_NAME_LENGTH); friends[i].name[friends[i].namelength] = '\0'; } num_friends = tox_count_friendlist(m); if (i == max_friends_index) ++max_friends_index; if (sort) sort_friendlist_index(); return; } } }
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8_t *group_pub_key) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); } else { uint8_t nick[TOX_MAX_NAME_LENGTH]; int n_len = tox_get_name(m, num, nick); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); nick[n_len] = '\0'; uint8_t msg[MAX_STR_SIZE]; snprintf(msg, sizeof(msg), "* Group chat invite from %s failed: too many windows are open.", nick); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); alert_window(prompt, WINDOW_ALERT_1, true); } } }
static void friendlist_onMessage(ToxWindow *self, Tox *m, int num, uint8_t *str, uint16_t len) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); } else { uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; tox_get_name(m, num, nick); nick[TOXIC_MAX_NAME_LENGTH] = '\0'; wprintw(prompt->window, "%s: %s\n", nick, str); prep_prompt_win(); wattron(prompt->window, COLOR_PAIR(RED)); wprintw(prompt->window, "* Warning: Too many windows are open.\n"); wattron(prompt->window, COLOR_PAIR(RED)); alert_window(prompt, WINDOW_ALERT_1, true); } } }
void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int num, bool sort) { if (max_friends_index < 0 || max_friends_index >= MAX_FRIENDS_NUM) return; int i; for (i = 0; i <= max_friends_index; ++i) { if (!friends[i].active) { friends[i].num = num; friends[i].active = true; friends[i].chatwin = -1; friends[i].online = false; friends[i].status = TOX_USERSTATUS_NONE; friends[i].namelength = tox_get_name(m, num, friends[i].name); tox_get_client_id(m, num, friends[i].pub_key); if (friends[i].namelength == -1 || friends[i].name[0] == '\0') { strcpy(friends[i].name, (uint8_t *) UNKNOWN_NAME); friends[i].namelength = strlen(UNKNOWN_NAME) + 1; } else { /* Enforce toxic's maximum name length */ friends[i].name[TOXIC_MAX_NAME_LENGTH] = '\0'; friends[i].namelength = strlen(friends[i].name) + 1; } num_friends = tox_count_friendlist(m); if (i == max_friends_index) ++max_friends_index; if (sort) sort_friendlist_index(m); return; } } }
void Core::loadFriends() { const uint32_t friendCount = tox_count_friendlist(tox); if (friendCount > 0) { // assuming there are not that many friends to fill up the whole stack int32_t *ids = new int32_t[friendCount]; tox_get_friendlist(tox, ids, friendCount); uint8_t clientId[TOX_CLIENT_ID_SIZE]; for (int32_t i = 0; i < static_cast<int32_t>(friendCount); ++i) { if (tox_get_client_id(tox, ids[i], clientId) == 0) { emit friendAdded(ids[i], CUserId::toString(clientId)); const int nameSize = tox_get_name_size(tox, ids[i]); if (nameSize > 0) { uint8_t *name = new uint8_t[nameSize]; if (tox_get_name(tox, ids[i], name) == nameSize) { emit friendUsernameLoaded(ids[i], CString::toString(name, nameSize)); } delete[] name; } const int statusMessageSize = tox_get_status_message_size(tox, ids[i]); if (statusMessageSize > 0) { uint8_t *statusMessage = new uint8_t[statusMessageSize]; if (tox_get_status_message(tox, ids[i], statusMessage, statusMessageSize) == statusMessageSize) { emit friendStatusMessageLoaded(ids[i], CString::toString(statusMessage, statusMessageSize)); } delete[] statusMessage; } checkLastOnline(ids[i]); } } delete[] ids; } }
static _Bool load_save(Tox *tox) { { uint8_t path[512], *p; uint32_t size; p = path + datapath(path); strcpy((char*)p, "tox_save"); void *data = file_raw((char*)path, &size); if(!data) { p = path + datapath_old(path); strcpy((char*)p, "tox_save"); data = file_raw((char*)path, &size); if (!data) { data = file_raw("tox_save", &size); if(!data) { return 0; } } } tox_load(tox, data, size); free(data); } friends = tox_count_friendlist(tox); uint32_t i = 0; while(i != friends) { int size; FRIEND *f = &friend[i]; uint8_t name[TOX_MAX_NAME_LENGTH]; f->msg.scroll = 1.0; tox_get_client_id(tox, i, f->cid); size = tox_get_name(tox, i, name); friend_setname(f, name, size); size = tox_get_status_message_size(tox, i); f->status_message = malloc(size); tox_get_status_message(tox, i, f->status_message, size); f->status_length = size; log_read(tox, i); i++; } self.name_length = tox_get_self_name(tox, self.name); self.statusmsg_length = tox_get_self_status_message_size(tox); self.statusmsg = malloc(self.statusmsg_length); tox_get_self_status_message(tox, self.statusmsg, self.statusmsg_length); self.status = tox_get_self_user_status(tox); return 1; }
wxString ToxFriend::getNick() { uint8_t nick[TOX_MAX_NAME_LENGTH]; int len = tox_get_name(m_tox, m_id, nick); printf("%d\n", len); return wxString::FromUTF8((const char*)nick, len); }
QString Core::getFriendUsername(int friendnumber) const { uint8_t name[TOX_MAX_NAME_LENGTH]; tox_get_name(tox, friendnumber, name); return CString::toString(name, tox_get_name_size(tox, friendnumber)); }