#include "common.h" int WhatsAppProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) { CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); return Proto_RecvMessage(hContact, pre); } void WhatsAppProto::onMessageForMe(FMessage *pMsg, bool paramBoolean) { bool isChatRoom = !pMsg->remote_resource.empty(); std::string msg; if (!pMsg->media_url.empty()) { msg = pMsg->media_url; if (pMsg->bindata_len) { TCHAR tszFilePath[MAX_PATH], tszFileName[MAX_PATH]; GetTempPath(_countof(tszFilePath), tszFilePath); mir_sntprintf(tszFileName, _countof(tszFileName), _T("%s\\%s.jpg"), tszFilePath, _A2T(pMsg->media_name.c_str())); FILE *out = _tfopen(tszFileName, _T("wb")); if (out != NULL) { fwrite(pMsg->bindata, 1, pMsg->bindata_len, out); fclose(out); std::string szFileName((const char*)_T2A(tszFileName)); std::replace(szFileName.begin(), szFileName.end(), '\\', '/'); std::replace(szFileName.begin(), szFileName.end(), ' ', '+'); msg.append("\nfile://"); msg += szFileName; } } } else msg = pMsg->data; if (isChatRoom) msg.insert(0, std::string("[").append(pMsg->notifyname).append("]: ")); MCONTACT hContact = this->AddToContactList(pMsg->key.remote_jid, 0, false, isChatRoom ? NULL : pMsg->notifyname.c_str(), isChatRoom); PROTORECVEVENT recv = { 0 }; recv.flags = PREF_UTF; recv.szMessage = const_cast(msg.c_str()); recv.timestamp = pMsg->timestamp; ProtoChainRecvMsg(hContact, &recv); m_pConnection->sendMessageReceived(pMsg); } int WhatsAppProto::SendMsg(MCONTACT hContact, int flags, const char *msg) { ptrA jid(getStringA(hContact, "ID")); if (jid == NULL) return 0; if (m_pConnection == NULL) { debugLogA("No connection"); return 0; } if (getByte(hContact, "SimpleChatRoom", 0) > 0 && getByte(hContact, "IsGroupMember", 0) == 0) { debugLogA("not a group member"); return 0; } int msgId = GetSerial(); try { time_t now = time(NULL); std::string id = Utilities::intToStr(now) + "-" + Utilities::intToStr(msgId); FMessage fmsg(std::string(jid), true, id); fmsg.timestamp = now; fmsg.data = msg; m_pConnection->sendMessage(&fmsg); utils::setStatusMessage(hContact, NULL); } catch (exception &e) { debugLogA("exception: %s", e.what()); ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)msgId, (LPARAM)e.what()); } catch (...) { debugLogA("unknown exception"); ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)msgId, (LPARAM)"Failed sending message"); } return msgId; } void WhatsAppProto::onIsTyping(const std::string& paramString, bool paramBoolean) { MCONTACT hContact = this->AddToContactList(paramString, 0, false); if (hContact != NULL) { CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM) paramBoolean ? PROTOTYPE_CONTACTTYPING_INFINITE : PROTOTYPE_CONTACTTYPING_OFF); } } int WhatsAppProto::UserIsTyping(MCONTACT hContact, int type) { if (hContact && isOnline()) { ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID)); if (jid && isOnline()) { if (type == PROTOTYPE_SELFTYPING_ON) m_pConnection->sendComposing((char*)jid); else m_pConnection->sendPaused((char*)jid); } } return 0; } void WhatsAppProto::onMessageStatusUpdate(FMessage* fmsg) { MCONTACT hContact = this->ContactIDToHContact(fmsg->key.remote_jid); if (hContact == 0) return; const TCHAR *ptszBy; switch (fmsg->status) { case FMessage::STATUS_RECEIVED_BY_SERVER: ptszBy = TranslateT("server"); break; case FMessage::STATUS_RECEIVED_BY_TARGET: ptszBy = pcli->pfnGetContactDisplayName(hContact, 0); break; default: return; } size_t delim = fmsg->key.id.find('-'); if (delim == string::npos) return; int msgId = atoi(fmsg->key.id.substr(delim+1).c_str()); ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)msgId, 0); time_t timestamp = atol(fmsg->key.id.substr(0, delim).c_str()); TCHAR ttime[64]; _tcsftime(ttime, SIZEOF(ttime), _T("%X"), localtime(×tamp)); utils::setStatusMessage(hContact, CMString(FORMAT, TranslateT("Message received: %s by %s"), ttime, ptszBy)); }