📄 chat.c
字号:
return; if(!strcmp(type, "result")) { jid = jabber_id_new(from); if(!jid) return; chat = jabber_chat_find(js, jid->node, jid->domain); jabber_id_free(jid); if(!chat) return; if(!(query = xmlnode_get_child(packet, "query"))) return; for(x = xmlnode_get_child(query, "x"); x; x = xmlnode_get_next_twin(x)) { const char *xmlns; if(!(xmlns = xmlnode_get_namespace(x))) continue; if(!strcmp(xmlns, "jabber:x:data")) { jabber_x_data_request(js, x, jabber_chat_register_x_data_cb, chat); return; } } } else if(!strcmp(type, "error")) { char *msg = jabber_parse_error(js, packet); purple_notify_error(js->gc, _("Registration error"), _("Registration error"), msg); if(msg) g_free(msg); return; } msg = g_strdup_printf("Unable to configure room %s", from); purple_notify_info(js->gc, _("Unable to configure"), _("Unable to configure"), msg); g_free(msg);}void jabber_chat_register(JabberChat *chat){ JabberIq *iq; char *room_jid; if(!chat) return; room_jid = g_strdup_printf("%s@%s", chat->room, chat->server); iq = jabber_iq_new_query(chat->js, JABBER_IQ_GET, "jabber:iq:register"); xmlnode_set_attrib(iq->node, "to", room_jid); g_free(room_jid); jabber_iq_set_callback(iq, jabber_chat_register_cb, NULL); jabber_iq_send(iq);}/* merge this with the function below when we get everyone on the same page wrt /commands */void jabber_chat_change_topic(JabberChat *chat, const char *topic){ if(topic && *topic) { JabberMessage *jm; jm = g_new0(JabberMessage, 1); jm->js = chat->js; jm->type = JABBER_MESSAGE_GROUPCHAT; jm->subject = purple_markup_strip_html(topic); jm->to = g_strdup_printf("%s@%s", chat->room, chat->server); jabber_message_send(jm); jabber_message_free(jm); } else { const char *cur = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(chat->conv)); char *buf, *tmp, *tmp2; if(cur) { tmp = g_markup_escape_text(cur, -1); tmp2 = purple_markup_linkify(tmp); buf = g_strdup_printf(_("current topic is: %s"), tmp2); g_free(tmp); g_free(tmp2); } else buf = g_strdup(_("No topic is set")); purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", buf, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL)); g_free(buf); }}void jabber_chat_set_topic(PurpleConnection *gc, int id, const char *topic){ JabberStream *js = gc->proto_data; JabberChat *chat = jabber_chat_find_by_id(js, id); if(!chat) return; jabber_chat_change_topic(chat, topic);}void jabber_chat_change_nick(JabberChat *chat, const char *nick){ xmlnode *presence; char *full_jid; PurplePresence *gpresence; PurpleStatus *status; JabberBuddyState state; char *msg; int priority; if(!chat->muc) { purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", _("Nick changing not supported in non-MUC chatrooms"), PURPLE_MESSAGE_SYSTEM, time(NULL)); return; } gpresence = purple_account_get_presence(chat->js->gc->account); status = purple_presence_get_active_status(gpresence); purple_status_to_jabber(status, &state, &msg, &priority); presence = jabber_presence_create(state, msg, priority); full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, nick); xmlnode_set_attrib(presence, "to", full_jid); g_free(full_jid); g_free(msg); jabber_send(chat->js, presence); xmlnode_free(presence);}void jabber_chat_part(JabberChat *chat, const char *msg){ char *room_jid; xmlnode *presence; room_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, chat->handle); presence = xmlnode_new("presence"); xmlnode_set_attrib(presence, "to", room_jid); xmlnode_set_attrib(presence, "type", "unavailable"); if(msg) { xmlnode *status = xmlnode_new_child(presence, "status"); xmlnode_insert_data(status, msg, -1); } jabber_send(chat->js, presence); xmlnode_free(presence); g_free(room_jid);}static void roomlist_disco_result_cb(JabberStream *js, xmlnode *packet, gpointer data){ xmlnode *query; xmlnode *item; const char *type; if(!js->roomlist) return; if(!(type = xmlnode_get_attrib(packet, "type")) || strcmp(type, "result")) { char *err = jabber_parse_error(js,packet); purple_notify_error(js->gc, _("Error"), _("Error retrieving room list"), err); purple_roomlist_set_in_progress(js->roomlist, FALSE); purple_roomlist_unref(js->roomlist); js->roomlist = NULL; g_free(err); return; } if(!(query = xmlnode_get_child(packet, "query"))) { char *err = jabber_parse_error(js, packet); purple_notify_error(js->gc, _("Error"), _("Error retrieving room list"), err); purple_roomlist_set_in_progress(js->roomlist, FALSE); purple_roomlist_unref(js->roomlist); js->roomlist = NULL; g_free(err); return; } for(item = xmlnode_get_child(query, "item"); item; item = xmlnode_get_next_twin(item)) { const char *name; PurpleRoomlistRoom *room; JabberID *jid; if(!(jid = jabber_id_new(xmlnode_get_attrib(item, "jid")))) continue; name = xmlnode_get_attrib(item, "name"); room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, jid->node, NULL); purple_roomlist_room_add_field(js->roomlist, room, jid->node); purple_roomlist_room_add_field(js->roomlist, room, jid->domain); purple_roomlist_room_add_field(js->roomlist, room, name ? name : ""); purple_roomlist_room_add(js->roomlist, room); jabber_id_free(jid); } purple_roomlist_set_in_progress(js->roomlist, FALSE); purple_roomlist_unref(js->roomlist); js->roomlist = NULL;}static void roomlist_cancel_cb(JabberStream *js, const char *server) { if(js->roomlist) { purple_roomlist_set_in_progress(js->roomlist, FALSE); purple_roomlist_unref(js->roomlist); js->roomlist = NULL; }}static void roomlist_ok_cb(JabberStream *js, const char *server){ JabberIq *iq; if(!js->roomlist) return; if(!server || !*server) { purple_notify_error(js->gc, _("Invalid Server"), _("Invalid Server"), NULL); return; } purple_roomlist_set_in_progress(js->roomlist, TRUE); iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items"); xmlnode_set_attrib(iq->node, "to", server); jabber_iq_set_callback(iq, roomlist_disco_result_cb, NULL); jabber_iq_send(iq);}char *jabber_roomlist_room_serialize(PurpleRoomlistRoom *room){ return g_strdup_printf("%s@%s", (char*)room->fields->data, (char*)room->fields->next->data);}PurpleRoomlist *jabber_roomlist_get_list(PurpleConnection *gc){ JabberStream *js = gc->proto_data; GList *fields = NULL; PurpleRoomlistField *f; if(js->roomlist) purple_roomlist_unref(js->roomlist); js->roomlist = purple_roomlist_new(purple_connection_get_account(js->gc)); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "room", TRUE); fields = g_list_append(fields, f); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "server", TRUE); fields = g_list_append(fields, f); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Description"), "description", FALSE); fields = g_list_append(fields, f); purple_roomlist_set_fields(js->roomlist, fields); purple_request_input(gc, _("Enter a Conference Server"), _("Enter a Conference Server"), _("Select a conference server to query"), js->chat_servers ? js->chat_servers->data : NULL, FALSE, FALSE, NULL, _("Find Rooms"), PURPLE_CALLBACK(roomlist_ok_cb), _("Cancel"), PURPLE_CALLBACK(roomlist_cancel_cb), purple_connection_get_account(gc), NULL, NULL, js); return js->roomlist;}void jabber_roomlist_cancel(PurpleRoomlist *list){ PurpleConnection *gc; JabberStream *js; gc = purple_account_get_connection(list->account); js = gc->proto_data; purple_roomlist_set_in_progress(list, FALSE); if (js->roomlist == list) { js->roomlist = NULL; purple_roomlist_unref(list); }}void jabber_chat_member_free(JabberChatMember *jcm){ g_free(jcm->handle); g_free(jcm->jid); g_free(jcm);}void jabber_chat_track_handle(JabberChat *chat, const char *handle, const char *jid, const char *affiliation, const char *role){ JabberChatMember *jcm = g_new0(JabberChatMember, 1); jcm->handle = g_strdup(handle); jcm->jid = g_strdup(jid); g_hash_table_replace(chat->members, jcm->handle, jcm); /* XXX: keep track of role and affiliation */}void jabber_chat_remove_handle(JabberChat *chat, const char *handle){ g_hash_table_remove(chat->members, handle);}gboolean jabber_chat_ban_user(JabberChat *chat, const char *who, const char *why){ JabberIq *iq; JabberChatMember *jcm = g_hash_table_lookup(chat->members, who); char *to; xmlnode *query, *item, *reason; if(!jcm || !jcm->jid) return FALSE; iq = jabber_iq_new_query(chat->js, JABBER_IQ_SET, "http://jabber.org/protocol/muc#admin"); to = g_strdup_printf("%s@%s", chat->room, chat->server); xmlnode_set_attrib(iq->node, "to", to); g_free(to); query = xmlnode_get_child(iq->node, "query"); item = xmlnode_new_child(query, "item"); xmlnode_set_attrib(item, "jid", jcm->jid); xmlnode_set_attrib(item, "affiliation", "outcast"); if(why) { reason = xmlnode_new_child(item, "reason"); xmlnode_insert_data(reason, why, -1); } jabber_iq_send(iq); return TRUE;}gboolean jabber_chat_affiliate_user(JabberChat *chat, const char *who, const char *affiliation){ char *to; JabberIq *iq; xmlnode *query, *item; JabberChatMember *jcm; jcm = g_hash_table_lookup(chat->members, who); if (!jcm || !jcm->jid) return FALSE; iq = jabber_iq_new_query(chat->js, JABBER_IQ_SET, "http://jabber.org/protocol/muc#admin"); to = g_strdup_printf("%s@%s", chat->room, chat->server); xmlnode_set_attrib(iq->node, "to", to); g_free(to); query = xmlnode_get_child(iq->node, "query"); item = xmlnode_new_child(query, "item"); xmlnode_set_attrib(item, "jid", jcm->jid); xmlnode_set_attrib(item, "affiliation", affiliation); jabber_iq_send(iq); return TRUE;}gboolean jabber_chat_role_user(JabberChat *chat, const char *who, const char *role){ char *to; JabberIq *iq; xmlnode *query, *item; JabberChatMember *jcm; jcm = g_hash_table_lookup(chat->members, who); if (!jcm || !jcm->handle) return FALSE; iq = jabber_iq_new_query(chat->js, JABBER_IQ_SET, "http://jabber.org/protocol/muc#admin"); to = g_strdup_printf("%s@%s", chat->room, chat->server); xmlnode_set_attrib(iq->node, "to", to); g_free(to); query = xmlnode_get_child(iq->node, "query"); item = xmlnode_new_child(query, "item"); xmlnode_set_attrib(item, "nick", jcm->handle); xmlnode_set_attrib(item, "role", role); jabber_iq_send(iq); return TRUE;}gboolean jabber_chat_kick_user(JabberChat *chat, const char *who, const char *why){ JabberIq *iq; JabberChatMember *jcm = g_hash_table_lookup(chat->members, who); char *to; xmlnode *query, *item, *reason; if(!jcm || !jcm->jid) return FALSE; iq = jabber_iq_new_query(chat->js, JABBER_IQ_SET, "http://jabber.org/protocol/muc#admin"); to = g_strdup_printf("%s@%s", chat->room, chat->server); xmlnode_set_attrib(iq->node, "to", to); g_free(to); query = xmlnode_get_child(iq->node, "query"); item = xmlnode_new_child(query, "item"); xmlnode_set_attrib(item, "jid", jcm->jid); xmlnode_set_attrib(item, "role", "none"); if(why) { reason = xmlnode_new_child(item, "reason"); xmlnode_insert_data(reason, why, -1); } jabber_iq_send(iq); return TRUE;}static void jabber_chat_disco_traffic_cb(JabberStream *js, xmlnode *packet, gpointer data){ JabberChat *chat; xmlnode *query; int id = GPOINTER_TO_INT(data); if(!(chat = jabber_chat_find_by_id(js, id))) return; /* defaults, in case the conference server doesn't * support this request */ chat->xhtml = TRUE; if(xmlnode_get_child(packet, "error")) { return; } if(!(query = xmlnode_get_child(packet, "query"))) return; /* disabling this until more MUC servers support * announcing this chat->xhtml = FALSE; for(x = xmlnode_get_child(query, "feature"); x; x = xmlnode_get_next_twin(x)) { const char *var = xmlnode_get_attrib(x, "var"); if(var && !strcmp(var, "http://jabber.org/protocol/xhtml-im")) { chat->xhtml = TRUE; } } */}void jabber_chat_disco_traffic(JabberChat *chat){ JabberIq *iq; xmlnode *query; char *room_jid; room_jid = g_strdup_printf("%s@%s", chat->room, chat->server); iq = jabber_iq_new_query(chat->js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info"); xmlnode_set_attrib(iq->node, "to", room_jid); query = xmlnode_get_child(iq->node, "query"); xmlnode_set_attrib(query, "node", "http://jabber.org/protocol/muc#traffic"); jabber_iq_set_callback(iq, jabber_chat_disco_traffic_cb, GINT_TO_POINTER(chat->id)); jabber_iq_send(iq); g_free(room_jid);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -