HANDLE CYahooProto::AddToList( int flags, PROTOSEARCHRESULT* psr ) { debugLogA("[YahooAddToList] Flags: %d", flags); if (!m_bLoggedIn) { debugLogA("[YahooAddToList] WARNING: WE ARE OFFLINE!"); return 0; } if (psr == NULL || psr->cbSize != sizeof( PROTOSEARCHRESULT )) { debugLogA("[YahooAddToList] Empty data passed?"); return 0; } char *id = psr->flags & PSR_UNICODE ? mir_utf8encodeW((wchar_t*)psr->id) : mir_utf8encode((char*)psr->id); HANDLE hContact = getbuddyH(id); if (hContact != NULL) { if (db_get_b(hContact, "CList", "NotOnList", 0)) { debugLogA("[YahooAddToList] Temporary Buddy:%s already on our buddy list", id); //return 0; } else { debugLogA("[YahooAddToList] Buddy:%s already on our buddy list", id); mir_free(id); return 0; } } else if (flags & PALF_TEMPORARY) { /* not on our list */ debugLogA("[YahooAddToList] Adding Temporary Buddy:%s ", id); } int protocol = psr->reserved[0]; debugLogA("Adding buddy:%s", id); hContact = add_buddy(id, id, protocol, flags); mir_free(id); return hContact; }
void CYahooProto::request_avatar(const char* who) { if (!getByte("ShowAvatars", 1)) { LOG(("Avatars disabled, but available for: %s", who)); return; } MCONTACT hContact = getbuddyH(who); if (!hContact) return; time_t cur_time; time(&cur_time); time_t last_chk = getDword(hContact, "PictLastCheck", 0); /* * time() - in seconds ( 60*60 = 1 hour) */ if (getDword(hContact, "PictCK", 0) == 0 || last_chk == 0 || (cur_time - last_chk) > 60) { setDword(hContact, "PictLastCheck", (DWORD)cur_time); LOG(("Requesting Avatar for: %s", who)); yahoo_request_buddy_avatar(m_id, who); } else LOG(("Avatar Not Available for: %s Last Check: %ld Current: %ld (Flood Check in Effect)", who, last_chk, cur_time)); }
void CYahooProto::ext_got_picture_checksum(const char *me, const char *who, int cksum) { LOG(("ext_yahoo_got_picture_checksum for %s checksum: %d", who, cksum)); MCONTACT hContact = getbuddyH(who); if (hContact == NULL) { LOG(("Buddy Not Found. Skipping avatar update")); return; } /* Last thing check the checksum and request new one if we need to */ if (!cksum || cksum == -1) { setDword(hContact, "PictCK", 0); reset_avatar(hContact); } else { if (getDword(hContact, "PictCK", 0) != cksum) { // Now save the new checksum. No rush requesting new avatar yet. setDword(hContact, "PictCK", cksum); // Need to delete the Avatar File!! TCHAR szFile[MAX_PATH]; GetAvatarFileName(hContact, szFile, _countof(szFile) - 1, 0); DeleteFile(szFile); // Reset the avatar and cleanup. reset_avatar(hContact); // Request new avatar here... (might also want to check the sharing status?) if (getByte("ShareAvatar", 0) == 2) request_avatar(who); } } }
void CYahooProto::ext_got_picture_update(const char *me, const char *who, int buddy_icon) { LOG(("ext_got_picture_update for %s buddy_icon: %d", who, buddy_icon)); MCONTACT hContact = getbuddyH(who); if (hContact == NULL) { LOG(("Buddy Not Found. Skipping avatar update")); return; } setByte(hContact, "AvatarType", buddy_icon); /* Last thing check the checksum and request new one if we need to */ reset_avatar(hContact); }
void CYahooProto::ChatEvent(const char* room, const char* who, int evt, const TCHAR* msg) { TCHAR* idt = mir_a2t(room); TCHAR* snt = mir_a2t(who); MCONTACT hContact = getbuddyH(who); TCHAR* nick = hContact ? (TCHAR*)pcli->pfnGetContactDisplayName(WPARAM(hContact), 0) : snt; GCDEST gcd = { m_szModuleName, idt, evt }; GCEVENT gce = { sizeof(gce), &gcd }; gce.dwFlags = GCEF_ADDTOLOG; gce.ptszNick = nick; gce.ptszUID = snt; gce.bIsMe = _stricmp(who, m_yahoo_id) == 0; gce.ptszStatus = gce.bIsMe ? TranslateT("Me") : TranslateT("Others"); gce.ptszText = msg; gce.time = time(NULL); CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); mir_free(snt); mir_free(idt); }
int __cdecl CYahooProto::OnGCEventHook(WPARAM, LPARAM lParam) { GCHOOK *gch = (GCHOOK*)lParam; if (!gch) return 1; if (mir_strcmp(gch->pDest->pszModule, m_szModuleName)) return 0; char *room = mir_t2a(gch->pDest->ptszID); char *who = mir_t2a(gch->ptszUID); switch (gch->pDest->iType) { case GC_SESSION_TERMINATE: { ChatRoom *cm = m_chatrooms.find((ChatRoom*)&room); if (cm) { yahoo_conference_logoff(m_id, NULL, cm->members, room); m_chatrooms.remove((ChatRoom*)&room); } } break; case GC_USER_MESSAGE: if (gch->ptszText && gch->ptszText[0]) { ChatRoom *cm = m_chatrooms.find((ChatRoom*)&room); if (cm) yahoo_conference_message(m_id, NULL, cm->members, room, T2Utf(gch->ptszText), 1); } break; case GC_USER_CHANMGR: DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, InviteToChatDialog, LPARAM(new InviteChatParam(room, this))); break; case GC_USER_PRIVMESS: CallService(MS_MSG_SENDMESSAGE, (WPARAM)getbuddyH(who)); break; case GC_USER_LOGMENU: switch (gch->dwData) { case 10: DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, InviteToChatDialog, LPARAM(new InviteChatParam(room, this))); break; case 20: ChatLeave(room); break; } break; case GC_USER_NICKLISTMENU: switch (gch->dwData) { case 10: CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)getbuddyH(who)); break; case 20: CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)getbuddyH(who)); break; case 110: ChatLeave(room); break; } break; case GC_USER_TYPNOTIFY: break; } mir_free(who); mir_free(room); return 0; }
void CYahooProto::ext_got_im(const char *me, const char *who, int protocol, const char *msg, long tm, int stat, int utf8, int buddy_icon, const char *seqn, int sendn) { char *umsg; const char *c = msg; int oidx = 0; LOG(("YAHOO_GOT_IM id:%s %s: %s (len: %d) tm:%lu stat:%i utf8:%i buddy_icon: %i", me, who, msg, lstrlenA(msg), tm, stat, utf8, buddy_icon)); if (stat == 2) { char z[1024]; mir_snprintf(z, SIZEOF(z), "Error sending message to %s", who); LOG((z)); ShowError( TranslateT("Yahoo Error"), _A2T(z)); return; } if (!msg) { LOG(("Empty Incoming Message, exiting.")); return; } if (getByte("IgnoreUnknown", 0)) { /* * Check our buddy list to see if we have it there. And if it's not on the list then we don't accept any IMs. */ if (getbuddyH(who) == NULL) { LOG(("Ignoring unknown user messages. User '%s'. Dropping Message.", who)); return; } } if ( BuddyIgnored( who )) { LOG(("User '%s' on our Ignore List. Dropping Message.", who)); return; } // make a bigger buffer for \n -> \r\n conversion (x2) umsg = (char *) alloca(lstrlenA(msg) * 2 + 1); while ( *c != '\0') { // Strip the font tag if (!_strnicmp(c,"<font ",6) || !_strnicmp(c,"</font>",6) || // strip the fade tag !_strnicmp(c, "<FADE ",6) || !_strnicmp(c,"</FADE>",7) || // strip the alternate colors tag !_strnicmp(c, "<ALT ",5) || !_strnicmp(c, "</ALT>",6)) { while ((*c++ != '>') && (*c != '\0')); } else // strip ANSI color combination if ((*c == 0x1b) && (*(c+1) == '[')) { while ((*c++ != 'm') && (*c != '\0')); } else if (*c != '\0') { umsg[oidx++] = *c; /* Adding \r to \r\n conversion */ if (*c == '\r' && *(c + 1) != '\n') umsg[oidx++] = '\n'; c++; } } umsg[oidx++]= '\0'; /* Need to strip off formatting stuff first. Then do all decoding/converting */ LOG(("%s: %s", who, umsg)); HANDLE hContact = add_buddy(who, who, protocol, PALF_TEMPORARY); //setWord(hContact, "yprotoid", protocol); Set_Protocol(hContact, protocol); PROTORECVEVENT pre = { 0 }; pre.flags = (utf8) ? PREF_UTF : 0; if (tm) { HANDLE hEvent = db_event_last(hContact); if (hEvent) { // contact has events DWORD dummy; DBEVENTINFO dbei = { sizeof (dbei) }; dbei.pBlob = (BYTE*)&dummy; dbei.cbBlob = 2; if (!db_event_get(hEvent, &dbei)) // got that event, if newer than ts then reset to current time if ((DWORD)tm < dbei.timestamp) tm = (long)time(NULL); } pre.timestamp = (DWORD)time(NULL); if ((DWORD)tm < pre.timestamp) pre.timestamp = tm; } else pre.timestamp = (DWORD)time(NULL); pre.szMessage = umsg; pre.lParam = 0; // Turn off typing CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); ProtoChainRecvMsg(hContact, &pre); // ack the message we just got if (seqn) yahoo_send_im_ack(m_id, me, who, seqn, sendn); if (buddy_icon < 0) return; //?? Don't generate floods!! setByte(hContact, "AvatarType", (BYTE)buddy_icon); if (buddy_icon != 2) reset_avatar(hContact); else if (getDword(hContact, "PictCK", 0) == 0) /* request the buddy image */ request_avatar(who); }
void CYahooProto::ext_got_picture(const char *me, const char *who, const char *pic_url, int cksum, int type) { MCONTACT hContact = 0; LOG(("[ext_yahoo_got_picture] for %s with url %s (checksum: %d) type: %d", who, pic_url, cksum, type)); /* Type: 1 - Send Avatar Info 2 - Got Avatar Info 3 - YIM6 didn't like my avatar? Expired? We need to invalidate and re-load */ switch (type) { case 1: { int cksum = 0; DBVARIANT dbv; /* need to send avatar info */ if (!getByte("ShowAvatars", 1)) { LOG(("[ext_yahoo_got_picture] We are not using/showing avatars!")); yahoo_send_picture_update(m_id, who, 0); // no avatar (disabled) return; } LOG(("[ext_yahoo_got_picture] Getting ready to send info!")); /* need to read CheckSum */ cksum = getDword("AvatarHash", 0); if (cksum) { if (!getString("AvatarURL", &dbv)) { LOG(("[ext_yahoo_got_picture] Sending url: %s checksum: %d to '%s'!", dbv.pszVal, cksum, who)); //void yahoo_send_picture_info(int id, const char *me, const char *who, const char *pic_url, int cksum) yahoo_send_picture_info(m_id, who, 2, dbv.pszVal, cksum); db_free(&dbv); break; } else LOG(("No AvatarURL???")); /* * Try to re-upload the avatar */ if (getByte("AvatarUL", 0) != 1) { // NO avatar URL?? if (!getTString("AvatarFile", &dbv)) { struct _stat statbuf; if (_tstat(dbv.ptszVal, &statbuf) != 0) { LOG(("[ext_yahoo_got_picture] Avatar File Missing? Can't find file: %s", dbv.ptszVal)); } else { setString("AvatarInv", who); SendAvatar(dbv.ptszVal); } db_free(&dbv); } else { LOG(("[ext_yahoo_got_picture] No Local Avatar File??? ")); } } else LOG(("[ext_yahoo_got_picture] Another avatar upload in progress?")); } } break; case 2: /* * We got Avatar Info for our buddy. */ if (!getByte("ShowAvatars", 1)) { LOG(("[ext_yahoo_got_picture] We are not using/showing avatars!")); return; } /* got avatar info, so set miranda up */ hContact = getbuddyH(who); if (!hContact) { LOG(("[ext_yahoo_got_picture] Buddy not on my buddy list?.")); return; } if (!cksum && pic_url) { const char *chk = strstr(pic_url, "chksum="); if (chk) cksum = strtol(chk + 7, NULL, 10); } if (!cksum || cksum == -1) { LOG(("[ext_yahoo_got_picture] Resetting avatar.")); setDword(hContact, "PictCK", 0); reset_avatar(hContact); } else { if (pic_url == NULL) { LOG(("[ext_yahoo_got_picture] WARNING: Empty URL for avatar?")); return; } TCHAR z[1024]; GetAvatarFileName(hContact, z, 1024, getByte(hContact, "AvatarType", 0)); if (getDword(hContact, "PictCK", 0) != cksum || _taccess(z, 0) != 0) { debugLogA("[ext_yahoo_got_picture] Checksums don't match or avatar file is missing. Current: %d, New: %d", getDword(hContact, "PictCK", 0), cksum); struct avatar_info *avt = (avatar_info*)malloc(sizeof(struct avatar_info)); avt->who = strdup(who); avt->pic_url = strdup(pic_url); avt->cksum = cksum; ForkThread(&CYahooProto::recv_avatarthread, avt); } } break; case 3: // Our Avatar is not good anymore? Need to re-upload?? /* who, pic_url, cksum */ { int mcksum = 0; DBVARIANT dbv; /* need to send avatar info */ if (!getByte("ShowAvatars", 1)) { LOG(("[ext_yahoo_got_picture] We are not using/showing avatars!")); yahoo_send_picture_update(m_id, who, 0); // no avatar (disabled) return; } LOG(("[ext_yahoo_got_picture] Getting ready to send info!")); /* need to read CheckSum */ mcksum = getDword("AvatarHash", 0); if (mcksum == 0) { /* this should NEVER Happen??? */ LOG(("[ext_yahoo_got_picture] No personal checksum? and Invalidate?!")); yahoo_send_picture_update(m_id, who, 0); // no avatar (disabled) return; } LOG(("[ext_yahoo_got_picture] My Checksum: %d", mcksum)); if (!getString("AvatarURL", &dbv)) { if (mir_strcmpi(pic_url, dbv.pszVal) == 0) { DBVARIANT dbv2; /*time_t ts; DWORD ae;*/ if (mcksum != cksum) LOG(("[ext_yahoo_got_picture] WARNING: Checksums don't match!")); /*time(&ts); ae = getDword("AvatarExpires", 0); if (ae != 0 && ae > (ts - 300)) { LOG(("[ext_yahoo_got_picture] Current Time: %lu Expires: %lu ", ts, ae)); LOG(("[ext_yahoo_got_picture] We just reuploaded! Stop screwing with Yahoo FT. ")); // don't leak stuff db_free(&dbv); break; }*/ LOG(("[ext_yahoo_got_picture] Buddy: %s told us this is bad??Expired??. Re-uploading", who)); delSetting("AvatarURL"); if (!getTString("AvatarFile", &dbv2)) { setString("AvatarInv", who); SendAvatar(dbv2.ptszVal); db_free(&dbv2); } else { LOG(("[ext_yahoo_got_picture] No Local Avatar File??? ")); } } else { LOG(("[ext_yahoo_got_picture] URL doesn't match? Tell them the right thing!!!")); yahoo_send_picture_info(m_id, who, 2, dbv.pszVal, mcksum); } // don't leak stuff db_free(&dbv); } else { LOG(("[ext_yahoo_got_picture] no AvatarURL?")); } } break; default: LOG(("[ext_yahoo_got_picture] Unknown request/packet type exiting!")); } LOG(("ext_yahoo_got_picture exiting")); }
void __cdecl CYahooProto::recv_avatarthread(void *pavt) { struct avatar_info *avt = (avatar_info*)pavt; int error = 0; TCHAR buf[4096]; if (avt == NULL) { debugLogA("AVT IS NULL!!!"); return; } if (!m_bLoggedIn) { debugLogA("We are not logged in!!!"); return; } // ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0); LOG(("yahoo_recv_avatarthread who:%s url:%s checksum: %d", avt->who, avt->pic_url, avt->cksum)); MCONTACT hContact = getbuddyH(avt->who); if (!hContact) { LOG(("ERROR: Can't find buddy: %s", avt->who)); error = 1; } else if (!error) { setDword(hContact, "PictCK", avt->cksum); setDword(hContact, "PictLoading", 1); } if (!error) { NETLIBHTTPREQUEST nlhr = { 0 }, *nlhrReply; nlhr.cbSize = sizeof(nlhr); nlhr.requestType = REQUEST_GET; nlhr.flags = NLHRF_NODUMP | NLHRF_GENERATEHOST | NLHRF_SMARTAUTHHEADER; nlhr.szUrl = avt->pic_url; nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&nlhr); if (nlhrReply) { if (nlhrReply->resultCode != 200) { LOG(("Update server returned '%d' instead of 200. It also sent the following: %s", nlhrReply->resultCode, nlhrReply->szResultDescr)); // make sure it's a real problem and not a problem w/ our connection yahoo_send_picture_info(m_id, avt->who, 3, avt->pic_url, avt->cksum); error = 1; } else if (nlhrReply->dataLength < 1 || nlhrReply->pData == NULL) { LOG(("No data??? Got %d bytes.", nlhrReply->dataLength)); error = 1; } else { GetAvatarFileName(hContact, buf, 1024, getByte(hContact, "AvatarType", 0)); DeleteFile(buf); LOG(("Saving file: %s size: %u", buf, nlhrReply->dataLength)); HANDLE myhFile = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (myhFile != INVALID_HANDLE_VALUE) { DWORD c; WriteFile(myhFile, nlhrReply->pData, nlhrReply->dataLength, &c, NULL); CloseHandle(myhFile); setDword(hContact, "PictLastCheck", 0); } else { LOG(("Can not open file for writing: %s", buf)); error = 1; } } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); } } if (getDword(hContact, "PictCK", 0) != avt->cksum) { LOG(("WARNING: Checksum updated during download?!")); error = 1; /* don't use this one? */ } setDword(hContact, "PictLoading", 0); LOG(("File download complete!?")); if (error) buf[0] = '\0'; free(avt->who); free(avt->pic_url); free(avt); PROTO_AVATAR_INFORMATION ai; ai.format = PA_FORMAT_PNG; ai.hContact = hContact; _tcsncpy_s(ai.filename, buf, _TRUNCATE); if (error) setDword(hContact, "PictCK", 0); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, !error ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)&ai, 0); }
static int ServiceParseYmsgrLink(WPARAM wParam, LPARAM lParam) { char *arg = (char*)lParam; UNREFERENCED_PARAMETER(wParam); if (arg == NULL) return 1; /* sanity check */ /* add user: ymsgr:addfriend?ID send message: ymsgr:sendim?ID&m=MESSAGE add chatroom: ymsgr:chat?ROOM */ /* skip leading prefix */ arg = strchr(arg, ':'); if (arg == NULL) return 1; /* parse failed */ for (++arg; *arg == '/'; ++arg); /* add a contact to the list */ if (!_strnicmp(arg, "addfriend?", 10)) { char *tok, *id = NULL; ADDCONTACTSTRUCT acs; PROTOSEARCHRESULT psr; if (*(arg += 10) == 0) return 1; /* parse failed */ tok = strtok(arg, "&"); /* first token */ if (tok != NULL) id = Netlib_UrlDecode(tok); if (id == NULL || *id == 0) return 1; /* parse failed */ if (getbuddyH(id) == NULL) { /* does not yet check if id is current user */ acs.handleType = HANDLE_SEARCHRESULT; acs.szProto = yahooProtocolName; acs.psr = &psr; memset(&psr, 0, sizeof(PROTOSEARCHRESULT)); psr.cbSize = sizeof(PROTOSEARCHRESULT); psr.nick.t = id; CallService(MS_ADDCONTACT_SHOW, 0, (LPARAM)&acs); } return 0; } /* send a message to a contact */ else if (!_strnicmp(arg, "sendim?", 7)) { char *tok, *id = NULL, *msg = NULL; MCONTACT hContact; if (*(arg += 7) == 0) return 1; /* parse failed */ tok = strtok(arg, "&"); /* first token */ if (tok != NULL) id = tok; while (tok != NULL) { if (!_strnicmp(tok, "m=", 2) && *(tok + 2) != 0) msg = Netlib_UrlDecode(tok + 2); tok = strtok(NULL, "&"); /* next token */ } if (id == NULL || *id == 0) return 1; /* parse failed */ if (ServiceExists(MS_MSG_SENDMESSAGE)) { /* does not yet check if sn is current user */ hContact = add_buddy(id, id, PALF_TEMPORARY); /* ensure contact is on list */ if (hContact != NULL) CallService(MS_MSG_SENDMESSAGE, hContact, (LPARAM)msg); } return 0; } /* open a chatroom */ else if (!_strnicmp(arg, "chat?", 5)) { char *tok, *rm = NULL; if (*(arg += 5) == 0) return 1; /* parse failed */ tok = strtok(arg, "&"); /* first token */ if (tok != NULL) rm = Netlib_UrlDecode(tok); if (rm == NULL) return 1; /* parse failed */ /* not yet implemented (rm contains name of chatroom)*/ return 0; } return 1; /* parse failed */ }