void fetion_got__chat() { conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, session->account); if (!conv) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who); } if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) { fetion_request_custom_smiley(slplink, smile, fetion_got_custom_smiley, NULL, obj); } }
void flist_fetch_emoticon(FListAccount *fla, const gchar *smiley, const gchar *character, PurpleConversation *convo) { FListFetchIcon *fli; int len; if(!purple_conv_custom_smiley_add(convo, smiley, "none", "0", TRUE)) { return; /* for some reason or another we can't add it */ } fli = g_new0(FListFetchIcon, 1); fli->character = g_strdup(character); fli->fla = fla; fli->convo = g_strdup(purple_conversation_get_name(convo)); fli->smiley = g_strdup(smiley); len = g_slist_length(fla->icon_requests); if(len < FLIST_MAX_ICON_REQUESTS) { flist_fetch_icon_real(fla, fli); } else { fla->icon_request_queue = g_slist_append(fla->icon_request_queue, fli); } }
void PurpleLine::write_message(line::Message &msg, bool replay) { std::string text; int flags = 0; time_t mtime = (time_t)(msg.createdTime / 1000); bool sent = (msg.from == profile.mid); if (std::find(recent_messages.cbegin(), recent_messages.cend(), msg.id) != recent_messages.cend()) { // We already processed this message. User is probably talking with himself. return; } // Hack if (msg.from == msg.to) push_recent_message(msg.id); PurpleConversation *conv = purple_find_conversation_with_account( (msg.toType == line::MIDType::USER ? PURPLE_CONV_TYPE_IM : PURPLE_CONV_TYPE_CHAT), ((!sent && msg.toType == line::MIDType::USER) ? msg.from.c_str() : msg.to.c_str()), acct); // If this is a new received IM, create the conversation if it doesn't exist if (!conv && !sent && msg.toType == line::MIDType::USER) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, msg.from.c_str()); // If this is a new conversation, we're not replaying history and history hasn't been fetched // yet, queue the message instead of showing it. if (conv && !replay) { auto *queue = (std::vector<line::Message> *) purple_conversation_get_data(conv, "line-message-queue"); if (queue) { queue->push_back(msg); return; } } // Replaying messages from history // Unfortunately Pidgin displays messages with this flag with odd formatting and no username. // Disable for now. //if (replay) // flags |= PURPLE_MESSAGE_NO_LOG; switch (msg.contentType) { case line::ContentType::NONE: // actually text case line::ContentType::LOCATION: if (msg.__isset.location) { line::Location &loc = msg.location; text = markup_escape(loc.title) + " | <a href=\"https://maps.google.com/?q=" + url_encode(loc.address) + "&ll=" + std::to_string(loc.latitude) + "," + std::to_string(loc.longitude) + "\">" + (loc.address.size() ? markup_escape(loc.address) : "(no address)") + "</a>"; } else { text = markup_escape(msg.text); } break; case line::ContentType::STICKER: { std::string id = get_sticker_id(msg); if (id == "") { text = "<em>[Broken sticker]</em>"; purple_debug_warning("line", "Got a broken sticker.\n"); } else { text = id; if (conv && purple_conv_custom_smiley_add(conv, id.c_str(), "id", id.c_str(), TRUE)) { http.request(get_sticker_url(msg), [this, id, conv](int status, const guchar *data, gsize len) { if (status == 200 && data && len > 0) { purple_conv_custom_smiley_write( conv, id.c_str(), data, len); } else { purple_debug_warning( "line", "Couldn't download sticker. Status: %d\n", status); } purple_conv_custom_smiley_close(conv, id.c_str()); }); } } } break; case line::ContentType::IMAGE: case line::ContentType::VIDEO: // Videos could really benefit from streaming... { std::string type_std = line::_ContentType_VALUES_TO_NAMES.at(msg.contentType); std::string id = "[LINE " + type_std + " " + msg.id + "]"; text = id; if (conv) { text += " <font color=\"#888888\">/open " + conv_attachment_add(conv, msg.contentType, msg.id) + "</font>"; } if (!conv || !purple_conv_custom_smiley_add(conv, id.c_str(), "id", id.c_str(), TRUE)) { break; } if (msg.contentPreview.size() > 0) { purple_conv_custom_smiley_write( conv, id.c_str(), (const guchar *)msg.contentPreview.c_str(), msg.contentPreview.size()); purple_conv_custom_smiley_close(conv, id.c_str()); } else { std::string preview_url = msg.contentMetadata.count("PREVIEW_URL") ? msg.contentMetadata["PREVIEW_URL"] : std::string(LINE_OS_URL) + "os/m/" + msg.id + "/preview"; http.request(preview_url, HTTPFlag::AUTH | HTTPFlag::LARGE, [this, id, conv](int status, const guchar *data, gsize len) { if (status == 200 && data && len > 0) { purple_conv_custom_smiley_write( conv, id.c_str(), data, len); } else { purple_debug_warning( "line", "Couldn't download image message. Status: %d\n", status); } purple_conv_custom_smiley_close(conv, id.c_str()); }); } } break; case line::ContentType::AUDIO: { text = "[Audio message"; if (msg.contentMetadata.count("AUDLEN")) { int len = 0; try { len = std::stoi(msg.contentMetadata["AUDLEN"]); } catch(...) { /* ignore */ } if (len > 0) { text += " " + std::to_string(len / 1000) + "." + std::to_string((len % 1000) / 100) + "s"; } } text += "]"; if (conv) { text += " <font color=\"#888888\">/open " + conv_attachment_add(conv, msg.contentType, msg.id) + "</font>"; } } break; // TODO: other content types default: text = "<em>[Not implemented: "; text += line::_ContentType_VALUES_TO_NAMES.at(msg.contentType); text += " message]</em>"; break; } if (sent) { // Messages sent by user (sync from other devices) write_message(conv, msg.from, text, mtime, flags | PURPLE_MESSAGE_SEND); } else { // Messages received from other users flags |= PURPLE_MESSAGE_RECV; if (replay) { // Write replayed messages instead of serv_got_* to avoid Pidgin's IM sound write_message(conv, msg.from, text, mtime, flags); } else { if (msg.toType == line::MIDType::USER) { serv_got_im( conn, msg.from.c_str(), text.c_str(), (PurpleMessageFlags)flags, mtime); } else if (msg.toType == line::MIDType::GROUP || msg.toType == line::MIDType::ROOM) { serv_got_chat_in( conn, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), msg.from.c_str(), (PurpleMessageFlags)flags, text.c_str(), mtime); } } } }
void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { MsnSession *session; MsnSlpLink *slplink; MsnSwitchBoard *swboard; MsnObject *obj; char **tokens; char *smile, *body_str; const char *body, *who, *sha1; guint tok; size_t body_len; PurpleConversation *conv; session = cmdproc->servconn->session; if (!purple_account_get_bool(session->account, "custom_smileys", TRUE)) return; swboard = cmdproc->data; conv = swboard->conv; body = msn_message_get_bin_data(msg, &body_len); if (!body || !body_len) return; body_str = g_strndup(body, body_len); /* MSN Messenger 7 may send more than one MSNObject in a single message... * Maybe 10 tokens is a reasonable max value. */ tokens = g_strsplit(body_str, "\t", 10); g_free(body_str); for (tok = 0; tok < 9; tok += 2) { if (tokens[tok] == NULL || tokens[tok + 1] == NULL) { break; } smile = tokens[tok]; obj = msn_object_new_from_string(purple_url_decode(tokens[tok + 1])); if (obj == NULL) break; who = msn_object_get_creator(obj); sha1 = msn_object_get_sha1(obj); slplink = msn_session_get_slplink(session, who); if (slplink->swboard != swboard) { if (slplink->swboard != NULL) /* * Apparently we're using a different switchboard now or * something? I don't know if this is normal, but it * definitely happens. So make sure the old switchboard * doesn't still have a reference to us. */ slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink); slplink->swboard = swboard; slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink); } /* If the conversation doesn't exist then this is a custom smiley * used in the first message in a MSN conversation: we need to create * the conversation now, otherwise the custom smiley won't be shown. * This happens because every GtkIMHtml has its own smiley tree: if * the conversation doesn't exist then we cannot associate the new * smiley with its GtkIMHtml widget. */ if (!conv) { conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who); } if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) { msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj); } msn_object_destroy(obj); obj = NULL; who = NULL; sha1 = NULL; } g_strfreev(tokens); }
void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) { MsnSession *session; MsnSlpLink *slplink; MsnObject *obj; char **tokens; char *smile, *body_str; const char *body, *who, *sha1; guint tok; size_t body_len; PurpleConversation *conv; session = cmdproc->session; if (!purple_account_get_bool_without_default_value(session->account, "custom_smileys")) return; body = msn_message_get_bin_data(msg, &body_len); body_str = g_strndup(body, body_len); /* MSN Messenger 7 may send more than one MSNObject in a single message... * Maybe 10 tokens is a reasonable max value. */ tokens = g_strsplit(body_str, "\t", 10); g_free(body_str); for (tok = 0; tok < 9; tok += 2) { if (tokens[tok] == NULL || tokens[tok + 1] == NULL) { break; } smile = tokens[tok]; { gchar *tmp; tmp = pecan_url_decode (tokens[tok + 1]); obj = msn_object_new_from_string(tmp); g_free(tmp); } if (obj == NULL) break; who = msn_object_get_creator(obj); sha1 = msn_object_get_sha1(obj); slplink = msn_session_get_slplink(session, who); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, session->account); /* If the conversation doesn't exist then this is a custom smiley * used in the first message in a MSN conversation: we need to create * the conversation now, otherwise the custom smiley won't be shown. * This happens because every GtkIMHtml has its own smiley tree: if * the conversation doesn't exist then we cannot associate the new * smiley with its GtkIMHtml widget. */ if (!conv) { //conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who); } if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) { msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj); } msn_object_destroy(obj); obj = NULL; who = NULL; sha1 = NULL; } g_strfreev(tokens); }