INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam) { PROTO_AVATAR_INFORMATIONT *AI = (PROTO_AVATAR_INFORMATIONT*)lParam; DBCachedContact *cc = CheckMeta(AI->hContact); if (cc == NULL) return GAIR_NOAVATAR; if (cc->nDefault == -1) return 0; MCONTACT hSub = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); if (!hSub) return GAIR_NOAVATAR; char *proto = GetContactProto(hSub); if (!proto) return GAIR_NOAVATAR; AI->hContact = hSub; INT_PTR result = ProtoCallService(proto, PS_GETAVATARINFOT, wParam, lParam); AI->hContact = cc->contactID; if (result != CALLSERVICE_NOTFOUND) return result; return GAIR_NOAVATAR; // fail }
/** Scans the \c CHANGES and call the appropriate function for each change. * * @param chg : Structure holding all the change info (See CHANGES). */ void ApplyChanges(CHANGES *chg) { HANDLE most_online; int i; // remove removed contacts for(i = 0; i < chg->num_deleted; i++) { Meta_Delete((WPARAM)chg->hDeletedContacts[i], 0); if(chg->hDeletedContacts[i] == chg->hDefaultContact) chg->hDefaultContact = 0; if(chg->hDeletedContacts[i] == chg->hOfflineContact) chg->hOfflineContact = 0; } // set contact positions for(i = 0; i < chg->num_contacts; i++) { if(Meta_GetContactNumber(chg->hContact[i]) != i) Meta_SwapContacts(chg->hMeta, Meta_GetContactNumber(chg->hContact[i]), i); } NotifyEventHooks(hSubcontactsChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); // set default if(chg->hDefaultContact) DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", Meta_GetContactNumber(chg->hDefaultContact)); else DBWriteContactSettingDword(chg->hMeta, META_PROTO, "Default", 0); NotifyEventHooks(hEventDefaultChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); // set offline if(chg->hOfflineContact) DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", Meta_GetContactNumber(chg->hOfflineContact)); else DBWriteContactSettingDword(chg->hMeta, META_PROTO, "OfflineSend", (DWORD)-1); // fix nick most_online = Meta_GetMostOnline(chg->hMeta); Meta_CopyContactNick(chg->hMeta, most_online); // fix status Meta_FixStatus(chg->hMeta); // fix avatar most_online = Meta_GetMostOnlineSupporting(chg->hMeta, PFLAGNUM_4, PF4_AVATARS); if(most_online) { PROTO_AVATAR_INFORMATION AI; AI.cbSize = sizeof(AI); AI.hContact = chg->hMeta; AI.format = PA_FORMAT_UNKNOWN; strcpy(AI.filename, "X"); if((int)CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&AI) == GAIR_SUCCESS) DBWriteContactSettingString(chg->hMeta, "ContactPhoto", "File",AI.filename); } if(MetaAPI_GetForceState((WPARAM)chg->hMeta, 0) != chg->force_default) MetaAPI_ForceDefault((WPARAM)chg->hMeta, 0); }
HANDLE Meta_GetActive(HANDLE hMeta) { HANDLE hActive = 0; if(DBGetContactSettingByte(hMeta, MODULE, "ForceDefault", 0)) hActive = (HANDLE)MetaAPI_GetDefault((WPARAM)hMeta, 0); if(!hActive) { if((hActive = (HANDLE)DBGetContactSettingDword(hMeta, MODULE, "ForceSend", 0)) == 0) { if((hActive = (HANDLE)DBGetContactSettingDword(hMeta, MODULE, "TempDefault", 0)) == 0) { hActive = Meta_GetMostOnline(hMeta); if(ContactStatus(hActive, ContactProto(hActive)) == ID_STATUS_OFFLINE) { hActive = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_IMSENDOFFLINE); } } } } return hActive; }
INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA*)lParam; DBCachedContact *cc = CheckMeta(ccs->hContact); if (cc == NULL || cc->nDefault == -1) return 0; MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_FILESEND); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (proto) return CallContactService(hMostOnline, PSS_FILE, ccs->wParam, ccs->lParam); return 0; // fail }
int Meta_HandleACK(WPARAM, LPARAM lParam) { ACKDATA *ack = (ACKDATA*)lParam; DBCachedContact *cc = CheckMeta(ack->hContact); if (cc == NULL) return 0; if (!strcmp(ack->szModule, META_PROTO)) return 0; // don't rebroadcast our own acks // if it's for something we don't support, ignore if (ack->type != ACKTYPE_MESSAGE && ack->type != ACKTYPE_CHAT && ack->type != ACKTYPE_FILE && ack->type != ACKTYPE_AWAYMSG && ack->type != ACKTYPE_AVATAR && ack->type != ACKTYPE_GETINFO) return 0; // change the hContact in the avatar info struct, if it's the avatar we're using - else drop it if (ack->type == ACKTYPE_AVATAR) { if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED || ack->result == ACKRESULT_STATUS) { DBVARIANT dbv; // change avatar if the most online supporting avatars changes, or if we don't have one MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); //if (AI.hContact == 0 || AI.hContact != hMostOnline) { if (ack->hContact == 0 || ack->hContact != hMostOnline) { return 0; } if (!db_get(ack->hContact, "ContactPhoto", "File", &dbv)) { db_set_ts(cc->contactID, "ContactPhoto", "File", dbv.ptszVal); db_free(&dbv); } if (ack->hProcess) { PROTO_AVATAR_INFORMATIONT AI; memcpy(&AI, (PROTO_AVATAR_INFORMATIONT *)ack->hProcess, sizeof(PROTO_AVATAR_INFORMATIONT)); if (AI.hContact) AI.hContact = cc->contactID; return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, (HANDLE)&AI, ack->lParam); } return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, 0, ack->lParam); } } return ProtoBroadcastAck(META_PROTO, cc->contactID, ack->type, ack->result, ack->hProcess, ack->lParam); }
INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA*)lParam; DBCachedContact *cc = CheckMeta(ccs->hContact); if (cc == NULL || cc->nDefault == -1) return 0; MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_1, PF1_MODEMSGRECV); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (!proto) return 0; ccs->hContact = hMostOnline; return CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam); }
INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA*)lParam; // This is a simple contact // (this should normally not happen, since linked contacts do not appear on the list.) DBCachedContact *cc = CheckMeta(ccs->hContact); if (cc == NULL || cc->nDefault == -1) return 0; MCONTACT hMostOnline = Meta_GetMostOnlineSupporting(cc, PFLAGNUM_4, PF4_AVATARS); if (!hMostOnline) return 0; char *proto = GetContactProto(hMostOnline); if (!proto) return 0; PROTO_AVATAR_INFORMATIONT AI; AI.cbSize = sizeof(AI); AI.hContact = ccs->hContact; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if (CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(ccs->hContact, "ContactPhoto", "File", AI.filename); hMostOnline = Meta_GetMostOnline(cc); Meta_CopyContactNick(cc, hMostOnline); if (!hMostOnline) return 0; ccs->hContact = hMostOnline; if (!ProtoServiceExists(proto, PSS_GETINFO)) return 0; // fail return CallContactService(ccs->hContact, PSS_GETINFO, ccs->wParam, ccs->lParam); }
int Meta_SettingChanged(WPARAM hContact, LPARAM lParam) { DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; char buffer[512]; // the only global options we're interested in if (hContact == 0) return 0; DBCachedContact *cc = currDb->m_cache->GetCachedContact(hContact); if (cc == NULL || !cc->IsSub()) return 0; DBCachedContact *ccMeta = currDb->m_cache->GetCachedContact(cc->parentID); if (ccMeta == NULL || !ccMeta->IsMeta()) return 0; // This contact is attached to a MetaContact. int contact_number = Meta_GetContactNumber(ccMeta, hContact); if (contact_number == -1) return 0; // exit - db corruption if (!strcmp(dcws->szSetting, "IP")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "IP", dcws->value.dVal); else db_unset(ccMeta->contactID, META_PROTO, "IP"); } else if (!strcmp(dcws->szSetting, "RealIP")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "RealIP", dcws->value.dVal); else db_unset(ccMeta->contactID, META_PROTO, "RealIP"); } else if (!strcmp(dcws->szSetting, "ListeningTo")) { switch (dcws->value.type) { case DBVT_ASCIIZ: db_set_s(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); break; case DBVT_UTF8: db_set_utf(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pszVal); break; case DBVT_WCHAR: db_set_ws(ccMeta->contactID, META_PROTO, "ListeningTo", dcws->value.pwszVal); break; case DBVT_DELETED: db_unset(ccMeta->contactID, META_PROTO, "ListeningTo"); break; } } else if (!strcmp(dcws->szSetting, "Nick") && dcws->value.type != DBVT_DELETED) { // subcontact nick has changed - update metacontact mir_snprintf(buffer, SIZEOF(buffer), "Nick%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); ptrT tszMyhandle(db_get_tsa(hContact, "CList", "MyHandle")); if (tszMyhandle == NULL) { mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); } // copy nick to metacontact, if it's the most online MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); Meta_CopyContactNick(ccMeta, hMostOnline); } else if (!strcmp(dcws->szSetting, "IdleTS")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", dcws->value.dVal); else if (dcws->value.type == DBVT_DELETED) db_set_dw(ccMeta->contactID, META_PROTO, "IdleTS", 0); } else if (!strcmp(dcws->szSetting, "LogonTS")) { if (dcws->value.type == DBVT_DWORD) db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", dcws->value.dVal); else if (dcws->value.type == DBVT_DELETED) db_set_dw(ccMeta->contactID, META_PROTO, "LogonTS", 0); } else if (!strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "MyHandle")) { if (dcws->value.type == DBVT_DELETED) { char *proto = GetContactProto(hContact); mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); DBVARIANT dbv; if (proto && !db_get_ts(hContact, proto, "Nick", &dbv)) { db_set_ts(ccMeta->contactID, META_PROTO, buffer, dbv.ptszVal); db_free(&dbv); } else db_unset(ccMeta->contactID, META_PROTO, buffer); } else { // subcontact clist displayname has changed - update metacontact mir_snprintf(buffer, SIZEOF(buffer), "CListName%d", contact_number); db_set(ccMeta->contactID, META_PROTO, buffer, &dcws->value); } // copy nick to metacontact, if it's the most online Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); } // subcontact changing status else if (!strcmp(dcws->szSetting, "Status") && dcws->value.type != DBVT_DELETED) { // update subcontact status setting mir_snprintf(buffer, SIZEOF(buffer), "Status%d", contact_number); db_set_w(ccMeta->contactID, META_PROTO, buffer, dcws->value.wVal); mir_snprintf(buffer, SIZEOF(buffer), "StatusString%d", contact_number); db_set_ts(ccMeta->contactID, META_PROTO, buffer, cli.pfnGetStatusModeDescription(dcws->value.wVal, 0)); // set status to that of most online contact MCONTACT hMostOnline = Meta_GetMostOnline(ccMeta); if (hMostOnline != db_mc_getDefault(ccMeta->contactID)) db_mc_notifyDefChange(ccMeta->contactID, hMostOnline); Meta_CopyContactNick(ccMeta, hMostOnline); Meta_FixStatus(ccMeta); // most online contact with avatar support might have changed - update avatar hMostOnline = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); if (hMostOnline) { PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; AI.hContact = ccMeta->contactID; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if (CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(ccMeta->contactID, "ContactPhoto", "File", AI.filename); } } return 0; }
HANDLE Meta_GetMostOnline(HANDLE hMeta) { return Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_1, PF1_IM); }
void Meta_RemoveContactNumber(HANDLE hMeta, int number) { int i, num_contacts, default_contact; HANDLE hContact;//, handle; char buffer[512], buffer2[512]; num_contacts = DBGetContactSettingDword(hMeta, META_PROTO, "NumContacts", 0); default_contact = DBGetContactSettingDword(hMeta, META_PROTO, "Default", -1); if(number >= 0 && number < num_contacts) { // get the handle hContact = Meta_GetContactHandle(hMeta, number); // make sure this contact thinks it's part of this metacontact if((HANDLE)DBGetContactSettingDword(hContact,META_PROTO,"Handle", 0) == hMeta) { // remove link to meta contact DBDeleteContactSetting(hContact,META_PROTO,"IsSubcontact"); DBDeleteContactSetting(hContact,META_PROTO,META_LINK); DBDeleteContactSetting(hContact,META_PROTO,"Handle"); DBDeleteContactSetting(hContact,META_PROTO,"ContactNumber"); // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) Meta_RestoreGroup(hContact); DBDeleteContactSetting(hContact,META_PROTO,"OldCListGroup"); //CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_PROTO); CallService(MS_PROTO_REMOVEFROMCONTACT,(WPARAM)hContact,(LPARAM)META_FILTER); // stop ignoring, if we were if(options.suppress_status) CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); } // remove history from metacontact //Meta_RemoveHistory(hMeta, hContact); // each contact from 'number' upwards will be moved down one // and the last one will be deleted for(i = number + 1; i < num_contacts; i++) { Meta_SwapContacts(hMeta, i, i-1); } // remove the last one strcpy(buffer, "Protocol"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Status"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Handle"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "StatusString"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Login"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "Nick"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); strcpy(buffer, "CListName"); strcat(buffer, _itoa((num_contacts - 1), buffer2, 10)); DBDeleteContactSetting(hMeta, META_PROTO, buffer); // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) if(default_contact >= number) { default_contact--; if(default_contact < 0) default_contact = 0; DBWriteContactSettingDword(hMeta, META_PROTO, "Default", (DWORD)default_contact); NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); } num_contacts--; DBWriteContactSettingDword(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); // fix nick hContact = Meta_GetMostOnline(hMeta); Meta_CopyContactNick(hMeta, hContact); // fix status Meta_FixStatus(hMeta); // fix avatar hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); if(hContact) { PROTO_AVATAR_INFORMATION AI; AI.cbSize = sizeof(AI); AI.hContact = hMeta; AI.format = PA_FORMAT_UNKNOWN; strcpy(AI.filename, "X"); if((int)CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&AI) == GAIR_SUCCESS) DBWriteContactSettingString(hMeta, "ContactPhoto", "File",AI.filename); } } }
void Meta_RemoveContactNumber(DBCachedContact *ccMeta, int number, bool bUpdateInfo) { if (ccMeta == NULL) return; // make sure this contact thinks it's part of this metacontact DBCachedContact *ccSub = currDb->m_cache->GetCachedContact(Meta_GetContactHandle(ccMeta, number)); if (ccSub != NULL) { if (ccSub->parentID == ccMeta->contactID) { db_unset(ccSub->contactID, "CList", "Hidden"); // stop ignoring, if we were if (options.bSuppressStatus) CallService(MS_IGNORE_UNIGNORE, ccSub->contactID, IGNOREEVENT_USERONLINE); } } // each contact from 'number' upwards will be moved down one // and the last one will be deleted for (int i = number+1; i < ccMeta->nSubs; i++) Meta_SwapContacts(ccMeta, i, i - 1); // remove the last one int id = ccMeta->nSubs - 1; char buffer[512]; mir_snprintf(buffer, "Handle%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Protocol%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Status%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "StatusString%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Login%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "Nick%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); mir_snprintf(buffer, "CListName%d", id); db_unset(ccMeta->contactID, META_PROTO, buffer); if (ccSub != NULL) { ccSub->parentID = 0; currDb->MetaDetouchSub(ccMeta, ccMeta->nSubs - 1); currDb->MetaSplitHistory(ccMeta, ccSub); } // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) if (ccMeta->nDefault >= number) { int iNumber = ccMeta->nDefault-1; if (iNumber < 0) iNumber = 0; db_mc_setDefaultNum(ccMeta->contactID, iNumber, true); } ccMeta->nSubs--; db_set_dw(ccMeta->contactID, META_PROTO, "NumContacts", ccMeta->nSubs); if (bUpdateInfo) { // fix nick Meta_CopyContactNick(ccMeta, Meta_GetMostOnline(ccMeta)); // fix status Meta_FixStatus(ccMeta); // fix avatar MCONTACT hContact = Meta_GetMostOnlineSupporting(ccMeta, PFLAGNUM_4, PF4_AVATARS); if (hContact) { PROTO_AVATAR_INFORMATION ai = { 0 }; ai.hContact = ccMeta->contactID; ai.format = PA_FORMAT_UNKNOWN; _tcsncpy_s(ai.filename, _T("X"), _TRUNCATE); if (CallProtoService(META_PROTO, PS_GETAVATARINFO, 0, (LPARAM)&ai) == GAIR_SUCCESS) db_set_ts(ccMeta->contactID, "ContactPhoto", "File", ai.filename); } } }
void Meta_RemoveContactNumber(HANDLE hMeta, int number) { int num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", 0); int default_contact = db_get_dw(hMeta, META_PROTO, "Default", -1); if (number < 0 && number >= num_contacts) return; // get the handle HANDLE hContact = Meta_GetContactHandle(hMeta, number); // make sure this contact thinks it's part of this metacontact if ((HANDLE)db_get_dw(hContact, META_PROTO, "Handle", 0) == hMeta) { // remove link to meta contact db_unset(hContact, META_PROTO, "IsSubcontact"); db_unset(hContact, META_PROTO, META_LINK); db_unset(hContact, META_PROTO, "Handle"); db_unset(hContact, META_PROTO, "ContactNumber"); // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) Meta_RestoreGroup(hContact); db_unset(hContact, META_PROTO, "OldCListGroup"); // stop ignoring, if we were if (options.suppress_status) CallService(MS_IGNORE_UNIGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE); } // each contact from 'number' upwards will be moved down one // and the last one will be deleted for (int i = number + 1; i < num_contacts; i++) Meta_SwapContacts(hMeta, i, i-1); // remove the last one char buffer[512], idStr[20]; _itoa(num_contacts-1, idStr, 10); strcpy(buffer, "Protocol"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Status"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Handle"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "StatusString"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Login"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "Nick"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); strcpy(buffer, "CListName"); strcat(buffer, idStr); db_unset(hMeta, META_PROTO, buffer); // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) if (default_contact >= number) { default_contact--; if (default_contact < 0) default_contact = 0; db_set_dw(hMeta, META_PROTO, "Default", (DWORD)default_contact); NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); } num_contacts--; db_set_dw(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); // fix nick hContact = Meta_GetMostOnline(hMeta); Meta_CopyContactNick(hMeta, hContact); // fix status Meta_FixStatus(hMeta); // fix avatar hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); if (hContact) { PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; AI.hContact = hMeta; AI.format = PA_FORMAT_UNKNOWN; _tcscpy(AI.filename, _T("X")); if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) db_set_ts(hMeta, "ContactPhoto", "File",AI.filename); } }