Esempio n. 1
0
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
}
Esempio n. 2
0
/** 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;
}
Esempio n. 4
0
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
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 10
0
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);
		}
	}
}
Esempio n. 11
0
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);
		}
	}
}
Esempio n. 12
0
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);
	}
}