📄 buddy.c
字号:
return; silc_free(userpk.data); } else if (filename && !client_entry->public_key) { if (!silc_pkcs_load_public_key(filename, &client_entry->public_key)) { /* Get public key with GETKEY */ cmd_ident = silc_client_command_call(client, conn, NULL, "GETKEY", client_entry->nickname, NULL); silc_client_command_pending(conn, SILC_COMMAND_GETKEY, cmd_ident, silcpurple_add_buddy_getkey_cb, r); return; } } else if (!client_entry->public_key) { /* Get public key with GETKEY */ cmd_ident = silc_client_command_call(client, conn, NULL, "GETKEY", client_entry->nickname, NULL); silc_client_command_pending(conn, SILC_COMMAND_GETKEY, cmd_ident, silcpurple_add_buddy_getkey_cb, r); return; } /* We have the public key, verify it. */ silcpurple_verify_public_key(client, conn, client_entry->nickname, SILC_CONN_CLIENT, client_entry->public_key, silcpurple_add_buddy_save, r);}static voidsilcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init){ SilcPurple sg = gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; SilcPurpleBuddyRes r; SilcBuffer attrs; const char *filename, *name = b->name; r = silc_calloc(1, sizeof(*r)); if (!r) return; r->client = client; r->conn = conn; r->b = b; r->init = init; /* See if we have this buddy's public key. If we do use that to search the details. */ filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key"); if (filename) { SilcPublicKey public_key; SilcAttributeObjPk userpk; if (!silc_pkcs_load_public_key(filename, &public_key)) return; /* Get all attributes, and use the public key to search user */ name = NULL; attrs = silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO, SILC_ATTRIBUTE_SERVICE, SILC_ATTRIBUTE_STATUS_MOOD, SILC_ATTRIBUTE_STATUS_FREETEXT, SILC_ATTRIBUTE_STATUS_MESSAGE, SILC_ATTRIBUTE_PREFERRED_LANGUAGE, SILC_ATTRIBUTE_PREFERRED_CONTACT, SILC_ATTRIBUTE_TIMEZONE, SILC_ATTRIBUTE_GEOLOCATION, SILC_ATTRIBUTE_USER_ICON, SILC_ATTRIBUTE_DEVICE_INFO, 0); userpk.type = "silc-rsa"; userpk.data = silc_pkcs_public_key_encode(public_key, &userpk.data_len); attrs = silc_attribute_payload_encode(attrs, SILC_ATTRIBUTE_USER_PUBLIC_KEY, SILC_ATTRIBUTE_FLAG_VALID, &userpk, sizeof(userpk)); silc_free(userpk.data); silc_pkcs_public_key_free(public_key); r->pubkey_search = TRUE; } else { /* Get all attributes */ attrs = silc_client_attributes_request(0); } /* Resolve */ silc_client_get_clients_whois(client, conn, name, NULL, attrs, silcpurple_add_buddy_resolved, r); silc_buffer_free(attrs);}void silcpurple_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group){ silcpurple_add_buddy_i(gc, buddy, FALSE);}void silcpurple_send_buddylist(PurpleConnection *gc){ PurpleBuddyList *blist; PurpleBlistNode *gnode, *cnode, *bnode; PurpleBuddy *buddy; PurpleAccount *account; account = purple_connection_get_account(gc); if ((blist = purple_get_blist()) != NULL) { for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) { if (!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) { if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; buddy = (PurpleBuddy *)bnode; if (purple_buddy_get_account(buddy) == account) silcpurple_add_buddy_i(gc, buddy, TRUE); } } } }}void silcpurple_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group){ silc_free(buddy->proto_data);}void silcpurple_idle_set(PurpleConnection *gc, int idle){ SilcPurple sg = gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; SilcAttributeObjService service; const char *server; int port; server = purple_account_get_string(sg->account, "server", "silc.silcnet.org"); port = purple_account_get_int(sg->account, "port", 706), memset(&service, 0, sizeof(service)); silc_client_attribute_del(client, conn, SILC_ATTRIBUTE_SERVICE, NULL); service.port = port; g_snprintf(service.address, sizeof(service.address), "%s", server); service.idle = idle; silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_SERVICE, &service, sizeof(service));}char *silcpurple_status_text(PurpleBuddy *b){ SilcPurple sg = b->account->gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; SilcClientID *client_id = b->proto_data; SilcClientEntry client_entry; SilcAttributePayload attr; SilcAttributeMood mood = 0; /* Get the client entry. */ client_entry = silc_client_get_client_by_id(client, conn, client_id); if (!client_entry) return NULL; /* If user is online, we show the mood status, if available. If user is offline or away that status is indicated. */ if (client_entry->mode & SILC_UMODE_DETACHED) return g_strdup(_("Detached")); if (client_entry->mode & SILC_UMODE_GONE) return g_strdup(_("Away")); if (client_entry->mode & SILC_UMODE_INDISPOSED) return g_strdup(_("Indisposed")); if (client_entry->mode & SILC_UMODE_BUSY) return g_strdup(_("Busy")); if (client_entry->mode & SILC_UMODE_PAGE) return g_strdup(_("Wake Me Up")); if (client_entry->mode & SILC_UMODE_HYPER) return g_strdup(_("Hyper Active")); if (client_entry->mode & SILC_UMODE_ROBOT) return g_strdup(_("Robot")); attr = silcpurple_get_attr(client_entry->attrs, SILC_ATTRIBUTE_STATUS_MOOD); if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { /* The mood is a bit mask, so we could show multiple moods, but let's show only one for now. */ if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) return g_strdup(_("Happy")); if (mood & SILC_ATTRIBUTE_MOOD_SAD) return g_strdup(_("Sad")); if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) return g_strdup(_("Angry")); if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) return g_strdup(_("Jealous")); if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) return g_strdup(_("Ashamed")); if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) return g_strdup(_("Invincible")); if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) return g_strdup(_("In Love")); if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) return g_strdup(_("Sleepy")); if (mood & SILC_ATTRIBUTE_MOOD_BORED) return g_strdup(_("Bored")); if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) return g_strdup(_("Excited")); if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) return g_strdup(_("Anxious")); } return NULL;}void silcpurple_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full){ SilcPurple sg = b->account->gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; SilcClientID *client_id = b->proto_data; SilcClientEntry client_entry; char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; char tmp[256]; /* Get the client entry. */ client_entry = silc_client_get_client_by_id(client, conn, client_id); if (!client_entry) return; if (client_entry->nickname) purple_notify_user_info_add_pair(user_info, _("Nickname"), client_entry->nickname); if (client_entry->username && client_entry->hostname) { g_snprintf(tmp, sizeof(tmp), "%s@%s", client_entry->username, client_entry->hostname); purple_notify_user_info_add_pair(user_info, _("Username"), tmp); } if (client_entry->mode) { memset(tmp, 0, sizeof(tmp)); silcpurple_get_umode_string(client_entry->mode, tmp, sizeof(tmp) - strlen(tmp)); purple_notify_user_info_add_pair(user_info, _("User Modes"), tmp); } silcpurple_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); if (statusstr) { purple_notify_user_info_add_pair(user_info, _("Message"), statusstr); g_free(statusstr); } if (full) { if (moodstr) { purple_notify_user_info_add_pair(user_info, _("Mood"), moodstr); g_free(moodstr); } if (contactstr) { purple_notify_user_info_add_pair(user_info, _("Preferred Contact"), contactstr); g_free(contactstr); } if (langstr) { purple_notify_user_info_add_pair(user_info, _("Preferred Language"), langstr); g_free(langstr); } if (devicestr) { purple_notify_user_info_add_pair(user_info, _("Device"), devicestr); g_free(devicestr); } if (tzstr) { purple_notify_user_info_add_pair(user_info, _("Timezone"), tzstr); g_free(tzstr); } if (geostr) { purple_notify_user_info_add_pair(user_info, _("Geolocation"), geostr); g_free(geostr); } }}static voidsilcpurple_buddy_kill(PurpleBlistNode *node, gpointer data){ PurpleBuddy *b; PurpleConnection *gc; SilcPurple sg; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); b = (PurpleBuddy *) node; gc = purple_account_get_connection(b->account); sg = gc->proto_data; /* Call KILL */ silc_client_command_call(sg->client, sg->conn, NULL, "KILL", b->name, "Killed by operator", NULL);}typedef struct { SilcPurple sg; SilcClientEntry client_entry;} *SilcPurpleBuddyWb;static voidsilcpurple_buddy_wb(PurpleBlistNode *node, gpointer data){ SilcPurpleBuddyWb wb = data; silcpurple_wb_init(wb->sg, wb->client_entry); silc_free(wb);}GList *silcpurple_buddy_menu(PurpleBuddy *buddy){ PurpleConnection *gc = purple_account_get_connection(buddy->account); SilcPurple sg = gc->proto_data; SilcClientConnection conn = sg->conn; const char *pkfile = NULL; SilcClientEntry client_entry = NULL; PurpleMenuAction *act; GList *m = NULL; SilcPurpleBuddyWb wb; pkfile = purple_blist_node_get_string((PurpleBlistNode *) buddy, "public-key"); client_entry = silc_client_get_client_by_id(sg->client, sg->conn, buddy->proto_data); if (client_entry && silc_client_private_message_key_is_set(sg->client, sg->conn, client_entry)) { act = purple_menu_action_new(_("Reset IM Key"), PURPLE_CALLBACK(silcpurple_buddy_resetkey), NULL, NULL); m = g_list_append(m, act); } else { act = purple_menu_action_new(_("IM with Key Exchange"), PURPLE_CALLBACK(silcpurple_buddy_keyagr), NULL, NULL); m = g_list_append(m, act); act = purple_menu_action_new(_("IM with Password"), PURPLE_CALLBACK(silcpurple_buddy_privkey_menu), NULL, NULL); m = g_list_append(m, act); } if (pkfile) { act = purple_menu_action_new(_("Show Public Key"), PURPLE_CALLBACK(silcpurple_buddy_showkey), NULL, NULL); m = g_list_append(m, act); } else { act = purple_menu_action_new(_("Get Public Key..."), PURPLE_CALLBACK(silcpurple_buddy_getkey_menu), NULL, NULL); m = g_list_append(m, act); } if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) { act = purple_menu_action_new(_("Kill User"), PURPLE_CALLBACK(silcpurple_buddy_kill), NULL, NULL); m = g_list_append(m, act); } if (client_entry) { wb = silc_calloc(1, sizeof(*wb)); wb->sg = sg; wb->client_entry = client_entry; act = purple_menu_action_new(_("Draw On Whiteboard"), PURPLE_CALLBACK(silcpurple_buddy_wb), (void *)wb, NULL); m = g_list_append(m, act); } return m;}void silcpurple_buddy_set_icon(PurpleConnection *gc, PurpleStoredImage *img){ SilcPurple sg = gc->proto_data; SilcClient client = sg->client; SilcClientConnection conn = sg->conn; SilcMime mime; char type[32]; const char *t; /* Remove */ if (!img) { silc_client_attribute_del(client, conn, SILC_ATTRIBUTE_USER_ICON, NULL); return; } /* Add */ mime = silc_mime_alloc(); if (!mime) return; t = purple_imgstore_get_extension(img); if (!t || !strcmp(t, "icon")) { silc_mime_free(mime); return; } if (!strcmp(t, "jpg")) t = "jpeg"; g_snprintf(type, sizeof(type), "image/%s", t); silc_mime_add_field(mime, "Content-Type", type); silc_mime_add_data(mime, purple_imgstore_get_data(img), purple_imgstore_get_size(img)); silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_USER_ICON, mime, sizeof(*mime)); silc_mime_free(mime);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -