Beispiel #1
0
void* AddTempGroup(HWND hwnd, ClcData *dat, const TCHAR *szName)
{
	int i = 0;
	int f = 0;
	DWORD groupFlags;

	if (wildcmp(_T2A(szName), "-@-HIDDEN-GROUP-@-"))
		return NULL;

	for (i = 1;; i++) {
		TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags);
		if (szGroupName == NULL) break;
		if (!mir_tstrcmpi(szGroupName, szName)) f = 1;
	}

	if (f)
		return NULL;

	char buf[20];
	_itoa_s(i - 1, buf, 10);

	TCHAR b2[255];
	mir_sntprintf(b2, _T("#%s"), szName);
	b2[0] = 1 | GROUPF_EXPANDED;
	db_set_ws(NULL, "CListGroups", buf, b2);
	pcli->pfnGetGroupName(i, &groupFlags);
	return cli_AddGroup(hwnd, dat, szName, groupFlags, i, 0);
}
Beispiel #2
0
void* AddTempGroup(HWND hwnd, ClcData *dat, const TCHAR *szName, DWORD flags, int groupId, int calcTotalMembers)
{
	int i = 0;
	int f = 0;
	DWORD groupFlags;

	if (wildcmp(_T2A(szName), "-@-HIDDEN-GROUP-@-"))
		return NULL;

	for (i = 1;; i++) {
		TCHAR *szGroupName = pcli->pfnGetGroupName(i, &groupFlags);
		if (szGroupName == NULL) break;
		if (!mir_tstrcmpi(szGroupName, szName)) f = 1;
	}
	if (!f) {
		char buf[20];
		TCHAR b2[255];
		void * res = NULL;
		mir_snprintf(buf, SIZEOF(buf), "%d", (i - 1));
		mir_sntprintf(b2, SIZEOF(b2), _T("#%s"), szName);
		b2[0] = 1 | GROUPF_EXPANDED;
		db_set_ws(NULL, "CListGroups", buf, b2);
		pcli->pfnGetGroupName(i, &groupFlags);
		res = cli_AddGroup(hwnd, dat, szName, groupFlags, i, 0);
		return res;
	}
	return NULL;
}
Beispiel #3
0
void LogToMessageWindow(XSTATUSCHANGE *xsc, BOOL opening)
{
	// cut message if needed
	if (opt.LTruncateMsg && (opt.LMsgLen > 0) && xsc->stzText && (_tcslen(xsc->stzText) > opt.LMsgLen)) {
		TCHAR buff[MAX_TEXT_LEN + 3];
		_tcsncpy(buff, xsc->stzText, opt.LMsgLen);
		buff[opt.LMsgLen] = 0;
		_tcscat(buff, _T("..."));
		mir_free(xsc->stzText);
		xsc->stzText = mir_tstrdup(buff);
	}

	TCHAR *Template = _T("");
	switch (xsc->action) {
	case NOTIFY_NEW_XSTATUS:
		Template = templates.LogNewXstatus; break;
	case NOTIFY_NEW_MESSAGE:
		Template = templates.LogNewMsg; break;
	case NOTIFY_REMOVE:
		Template = templates.LogRemove; break;
	case NOTIFY_OPENING_ML:
		Template = templates.LogOpening; break;
	}

	TCHAR stzLogText[2*MAX_TEXT_LEN];
	TCHAR stzLastLog[2*MAX_TEXT_LEN];
	ReplaceVars(xsc, Template, templates.LogDelimiter, stzLogText);
	DBGetStringDefault(xsc->hContact, MODULE, DB_LASTLOG, stzLastLog, SIZEOF(stzLastLog), _T(""));

	if (!opt.KeepInHistory || !(opt.PreventIdentical && _tcscmp(stzLastLog, stzLogText) == 0))
		db_set_ws(xsc->hContact, MODULE, DB_LASTLOG, stzLogText);
}
Beispiel #4
0
void AddContactToGroup(MCONTACT hContact, char *group)
{
	const int MAX_SIZE = 1024;
	wchar_t wide[MAX_SIZE] = {0};
	MultiByteToWideChar(currentCodePage, 0, group, -1, wide, MAX_SIZE);
	db_set_ws(hContact, "CList", "Group", wide);
}
void saveSettingsConnections(struct CONNECTION *connHead)
{
	char buff[128];
	int i=0;
	struct CONNECTION *tmp=connHead;
	while(tmp!=NULL)
	{

		mir_snprintf(buff,sizeof(buff), "%dFilterIntIp", i);
		db_set_ts(NULL, PLUGINNAME, buff, tmp->strIntIp);
		mir_snprintf(buff,sizeof(buff), "%dFilterExtIp", i);
		db_set_ts(NULL, PLUGINNAME, buff, tmp->strExtIp);
		mir_snprintf(buff,sizeof(buff), "%dFilterPName", i);
		db_set_ws(NULL, PLUGINNAME, buff, tmp->PName);
		mir_snprintf(buff,sizeof(buff), "%dFilterIntPort", i);
		db_set_dw(NULL, PLUGINNAME, buff, tmp->intIntPort);
		mir_snprintf(buff,sizeof(buff), "%dFilterExtPort", i);
		db_set_dw(NULL, PLUGINNAME, buff, tmp->intExtPort);
		mir_snprintf(buff,sizeof(buff), "%dFilterAction", i);
		db_set_dw(NULL, PLUGINNAME, buff, tmp->Pid);
		i++;
		tmp=tmp->next;
	}
	settingFiltersCount=i;
	db_set_dw(NULL, PLUGINNAME, "FiltersCount", settingFiltersCount );
	
}
BOOL convertSetting(MCONTACT hContact, char* module, char* setting, int toType) // 0 = byte, 1 = word, 2 = dword, 3 = string, 4 = unicode
{
	DBVARIANT dbv = { 0 };
	BOOL Result = 0;

	if (!GetSetting(hContact, module, setting, &dbv)) {
		switch (dbv.type) {
		case DBVT_BYTE:
			Result = Convert(hContact, module, setting, dbv.bVal, toType);
			break;

		case DBVT_WORD:
			Result = Convert(hContact, module, setting, dbv.wVal, toType);
			break;

		case DBVT_DWORD:
			Result = Convert(hContact, module, setting, dbv.dVal, toType);
			break;

		case DBVT_ASCIIZ:
			if (toType == 4) // convert to UNICODE
			{
				int len = (int)strlen(dbv.pszVal) + 1;
				WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
				MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, wc, len);
				Result = !db_set_ws(hContact, module, setting, wc);
			}
			else if (strlen(dbv.pszVal) < 11 && toType != 3) {
				int val = atoi(dbv.pszVal);
				if (val == 0 && dbv.pszVal[0] != '0')
					break;

				Result = Convert(hContact, module, setting, val, toType);
			}
			break;

		case DBVT_UTF8:
			if (toType == 3) { // convert to ANSI
				int len = (int)strlen(dbv.pszVal) + 1;
				char *sz = (char*)_alloca(len * 3);
				WCHAR *wc = (WCHAR*)_alloca(len*sizeof(WCHAR));
				MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, wc, len);
				WideCharToMultiByte(CP_ACP, 0, wc, -1, sz, len, NULL, NULL);
				Result = !db_set_s(hContact, module, setting, sz);
			}
			break;
		}

		if (!Result)
			msg(Translate("Cannot Convert!"), modFullname);

		db_free(&dbv);
	}

	return Result;
}
Beispiel #7
0
int setTextValue(MCONTACT hContact, const char *module, const char *setting, TCHAR *value, int type)
{
#ifdef _UNICODE
	if (type == DBVT_UTF8 || type == DBVT_WCHAR)
		return !db_set_ws(hContact, module, setting, value);

	if (type == DBVT_ASCIIZ && IsRealUnicode(value))
		return 0;
#endif
	return !db_set_s(hContact, module, setting, _T2A(value));
}
Beispiel #8
0
INT_PTR AddSimpleMessage(WPARAM wParam, LPARAM lParam)
{
	MCONTACT hContact = wParam;
	TCHAR* message = (TCHAR*)lParam;
	db_set_ws(hContact, modname, "PounceMsg", message);
	db_set_w(hContact, modname, "SendIfMyStatusIsFLAG", (WORD)db_get_w(NULL, modname, "SendIfMyStatusIsFLAG",1));
	db_set_w(hContact, modname, "SendIfTheirStatusIsFLAG", (WORD)db_get_w(NULL, modname, "SendIfTheirStatusIsFLAG",1));
	db_set_b(hContact, modname, "Reuse", (BYTE)db_get_b(NULL, modname, "Reuse",0));
	db_set_b(hContact, modname, "GiveUpDays", (BYTE)db_get_b(NULL, modname, "GiveUpDays",0));
	db_set_dw(hContact, modname, "GiveUpDate", (DWORD)(db_get_b(hContact, modname, "GiveUpDays",0)*SECONDSINADAY));
	return 0;
}
Beispiel #9
0
MIRANDA_HOOK_EVENT(ME_DB_EVENT_ADDED, hContact, hDbEvent)
{
	DBEVENTINFO dbei = { sizeof(dbei) };
	dbei.cbBlob = db_event_getBlobSize(hDbEvent);
	if (dbei.cbBlob == -1)
		return 0;

	dbei.pBlob = (BYTE*)alloca(dbei.cbBlob);
	db_event_get(hDbEvent, &dbei);

	// if event is in protocol that is not despammed
	if (!ProtoInList(dbei.szModule))
		return 0;

	// event is an auth request
	if (gbHandleAuthReq) {
		if (!(dbei.flags & DBEF_SENT) && !(dbei.flags & DBEF_READ) && dbei.eventType == EVENTTYPE_AUTHREQUEST) {
			MCONTACT hcntct = DbGetAuthEventContact(&dbei);

			// if request is from unknown or not marked Answered contact
			int a = db_get_b(hcntct, "CList", "NotOnList", 0);
			int b = !db_get_b(hcntct, pluginName, "Answered", 0);

			if (a && b) {
				// ...send message

				if (gbHideContacts)
					db_set_b(hcntct, "CList", "Hidden", 1);
				if (gbSpecialGroup)
					db_set_ws(hcntct, "CList", "Group", gbSpammersGroup.c_str());
				BYTE msg = 1;
				if (gbIgnoreURL) {
					TCHAR* EventText = ReqGetText(&dbei); //else return NULL
					msg = !IsUrlContains(EventText);
					mir_free(EventText);
				}
				if (gbInvisDisable) {
					if (CallProtoService(dbei.szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE)
						msg = 0;
					else if (db_get_w(hContact, dbei.szModule, "ApparentMode", 0) == ID_STATUS_OFFLINE)
						msg = 0; //is it useful ?
				}
				if (msg) {
					ptrA buff(mir_utf8encodeW(variables_parse(gbAuthRepl, hcntct).c_str()));
					CallContactService(hcntct, PSS_MESSAGE, 0, (LPARAM)buff);
				}
				return 1;
			}
		}
	}
	return 0;
}
int CMPlugin::Load()
{
	HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded);
	DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &g_hMainThread, THREAD_SET_CONTEXT, false, 0);
	InitOptions();

	if (db_get_b(NULL, MODULENAME, DB_SETTINGSVER, 0) < 1) {
		TCString Str;
		Str = db_get_s(NULL, MODULENAME, DB_IGNORESUBSTRINGS, L"");
		if (Str.GetLen()) // fix incorrect regexp from v0.1.1.0
			db_set_ws(NULL, MODULENAME, DB_IGNORESUBSTRINGS, Str.Replace(L"/Miranda[0-9A-F]{8}/", L"/[0-9A-F]{8}(\\W|$)/"));

		db_set_b(NULL, MODULENAME, DB_SETTINGSVER, 1);
	}
	return 0;
}
Beispiel #11
0
MCONTACT CDropbox::GetDefaultContact()
{
	if (!hDefaultContact)
		hDefaultContact = db_find_first(MODULE);

	if (!hDefaultContact) {
		hDefaultContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
		if (!Proto_AddToContact(hDefaultContact, MODULE)) {
			db_set_s(NULL, MODULE, "Nick", MODULE);
			db_set_s(hDefaultContact, MODULE, "Nick", MODULE);
			db_set_ws(hDefaultContact, "CList", "MyHandle", L"Dropbox");
		}
		db_set_w(hDefaultContact, MODULE, "Status", HasAccessToken() ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE);
	}

	return hDefaultContact;
}
Beispiel #12
0
INT_PTR AddToPounce(WPARAM wParam, LPARAM lParam)
{
	MCONTACT hContact = wParam;
	TCHAR* message = (TCHAR*)lParam;
	DBVARIANT dbv;
	if (!db_get_ts(hContact, modname, "PounceMsg",&dbv))
	{
		TCHAR* newPounce = (TCHAR*)mir_alloc(mir_tstrlen(dbv.ptszVal) + mir_tstrlen(message) + 1);
		if (!newPounce) return 1;
		mir_tstrcpy(newPounce, dbv.ptszVal);
		mir_tstrcat(newPounce, message);
		db_set_ws(hContact, modname, "PounceMsg", newPounce);
		mir_free(newPounce);
		db_free(&dbv);
	}
	else AddSimpleMessage(hContact, (LPARAM)message);
	return 0;
}
Beispiel #13
0
void AddNewGroup(const char *newGroup)
{
	int index = GetNextGroupIndex();
	
	char tmp[128];
	char group[1024];

	*group = 1;
	strncpy_s((group + 1), (_countof(group) - 1), newGroup, _TRUNCATE);
	
	mir_snprintf(tmp, "%d", index);
	const int MAX_SIZE = 1024;
	wchar_t wide[MAX_SIZE] = {0};
	*wide = 1;
	MultiByteToWideChar(currentCodePage, 0, group + 1, -1, wide + 1, MAX_SIZE - 1);
	db_set_ws(NULL, CLIST_GROUPS, tmp, wide);
	
	availableGroups.Add(_strdup(group + 1));
}
Beispiel #14
0
MCONTACT CDropbox::GetDefaultContact()
{
	if (!hDefaultContact)
		hDefaultContact = db_find_first(MODULE);

	if (!hDefaultContact)
	{
		hDefaultContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
		if (!CallService(MS_PROTO_ADDTOCONTACT, hDefaultContact, (LPARAM)MODULE))
		{
			db_set_s(NULL, MODULE, "Nick", MODULE);
			db_set_s(hDefaultContact, MODULE, "Nick", MODULE);
			db_set_ws(hDefaultContact, "CList", "MyHandle", L"Dropbox");

			int status = db_get_w(hDefaultContact, MODULE, "Status", ID_STATUS_OFFLINE);
			if (HasAccessToken() && status == ID_STATUS_OFFLINE)
				db_set_w(hDefaultContact, MODULE, "Status", ID_STATUS_ONLINE);
		}
	}

	return hDefaultContact;
}
Beispiel #15
0
static MCONTACT AddContact(HWND hdlgProgress, char* szProto, char* pszUniqueSetting, DBVARIANT* id, const TCHAR* pszUserID, TCHAR *nick, TCHAR *group)
{
    MCONTACT hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
    if (CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)szProto) != 0) {
        CallService(MS_DB_CONTACT_DELETE, hContact, 0);
        AddMessage(LPGENT("Failed to add %S contact %s"), szProto, pszUserID);
        return INVALID_CONTACT_ID;
    }

    mySet(hContact, szProto, pszUniqueSetting, id);

    CreateGroup(group, (MCONTACT)hContact);

    if (nick && *nick) {
        db_set_ws((MCONTACT)hContact, "CList", "MyHandle", nick);
        AddMessage(LPGENT("Added %S contact %s, '%s'"), szProto, pszUserID, nick);
    }
    else AddMessage(LPGENT("Added %S contact %s"), szProto, pszUserID);

    srcDb->FreeVariant(id);
    return hContact;
}
Beispiel #16
0
int MsgAck(WPARAM, LPARAM lParam) 
{ 
	ACKDATA *ack=(ACKDATA*)lParam; 

	if (ack && ack->cbSize == sizeof(ACKDATA) && ack->type == ACKTYPE_MESSAGE) {
		if (ack->hProcess == (HANDLE)WindowList_Find(hWindowList,ack->hContact)) { 
			if (db_get_b(NULL, modname, "ShowDeliveryMessages", 1))
				CreateMessageAcknowlegedWindow(ack->hContact,ack->result == ACKRESULT_SUCCESS);
			if (ack->result == ACKRESULT_SUCCESS) {
				// wrtie it to the DB
				DBEVENTINFO dbei = { 0 };
				DBVARIANT dbv;
				int reuse = db_get_b(ack->hContact,modname, "Reuse", 0);
				if (!db_get_ts(ack->hContact, modname, "PounceMsg", &dbv) && (dbv.ptszVal[0] != '\0')) {
					T2Utf pszUtf(dbv.ptszVal);
					dbei.cbSize = sizeof(dbei);
					dbei.eventType = EVENTTYPE_MESSAGE;
					dbei.flags = DBEF_UTF | DBEF_SENT;
					dbei.szModule = (char*)ack->szModule;
					dbei.timestamp = time(NULL);
					dbei.cbBlob = (int)mir_strlen(pszUtf) + 1;
					dbei.pBlob = (PBYTE)(char*)pszUtf;
					db_event_add(ack->hContact, &dbei);
				}
				// check to reuse
				if (reuse > 1)
					db_set_b(ack->hContact, modname, "Reuse", (BYTE)(reuse-1));
				else {
					db_set_b(ack->hContact,modname, "Reuse", 0);
					db_set_ws(ack->hContact, modname, "PounceMsg", _T(""));
				}
			}
			WindowList_Remove(hWindowList,(HWND)ack->hProcess);
		}
	} 
	return 0; 
} 
Beispiel #17
0
INT_PTR cfg::writeTString(const MCONTACT hContact, const char *szModule = 0, const char *szSetting = 0, const wchar_t *str = 0)
{
	return(db_set_ws(hContact, szModule, szSetting, str));
}
INT_PTR CALLBACK EditSettingDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_INITDIALOG:
	{
		char tmp[32];
		SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam);
		switch (((struct DBsetting*)lParam)->dbv.type)
		{
		case DBVT_BYTE:
			ShowWindow(GetDlgItem(hwnd, IDC_STRING), SW_HIDE);
			if (!((struct DBsetting*)lParam)->setting[0])
			{
				SetWindowText(hwnd, Translate("New BYTE value"));
			}
			else
			{
				SetWindowText(hwnd, Translate("Edit BYTE value"));
				SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
				SetDlgItemText(hwnd, IDC_SETTINGVALUE, itoa(((struct DBsetting*)lParam)->dbv.bVal, tmp, 10));
			}
			CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_DECIMAL);
			CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_BYTE);
			break;
		case DBVT_WORD:
			ShowWindow(GetDlgItem(hwnd, IDC_STRING), SW_HIDE);
			if (!((struct DBsetting*)lParam)->setting[0])
			{
				SetWindowText(hwnd, Translate("New WORD value"));
			}
			else
			{
				SetWindowText(hwnd, Translate("Edit WORD value"));
				SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
				SetDlgItemText(hwnd, IDC_SETTINGVALUE, itoa(((struct DBsetting*)lParam)->dbv.wVal, tmp, 10));
			}
			CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_DECIMAL);
			CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_WORD);
			break;
		case DBVT_DWORD:
			ShowWindow(GetDlgItem(hwnd, IDC_STRING), SW_HIDE);
			if (!((struct DBsetting*)lParam)->setting[0])
			{
				SetWindowText(hwnd, Translate("New DWORD value"));
			}
			else
			{
				char text[32];
				SetWindowText(hwnd, Translate("Edit DWORD value"));
				SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
				mir_snprintf(text, SIZEOF(text), "%X", ((struct DBsetting*)lParam)->dbv.dVal);
				SetDlgItemText(hwnd, IDC_SETTINGVALUE, text);
			}
			CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, CHK_HEX);
			CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, CHK_DWORD);
			break;
		case DBVT_ASCIIZ:
			ShowWindow(GetDlgItem(hwnd, IDC_STRING), SW_SHOW);
			ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_HEX), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, GRP_BASE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, GRP_TYPE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_BYTE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_WORD), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_DWORD), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_STRING), SW_HIDE);
			if (!((struct DBsetting*)lParam)->setting[0])
			{
				SetWindowText(hwnd, Translate("New STRING value"));
			}
			else
			{
				SetWindowText(hwnd, Translate("Edit STRING value"));
				SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
				SetDlgItemText(hwnd, IDC_STRING, ((struct DBsetting*)lParam)->dbv.pszVal);
			}
			break;
		case DBVT_UTF8:
			ShowWindow(GetDlgItem(hwnd, IDC_STRING), SW_SHOW);
			ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_HEX), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, GRP_BASE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, GRP_TYPE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_BYTE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_WORD), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_DWORD), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_STRING), SW_HIDE);
			if (!((struct DBsetting*)lParam)->setting[0])
			{
				SetWindowText(hwnd, Translate("New UNICODE value"));
			}
			else
			{
				char *tmp = (((struct DBsetting*)lParam)->dbv.pszVal);
				int length = (int)strlen(tmp) + 1;
				WCHAR *wc = (WCHAR*)_alloca(length*sizeof(WCHAR));
				MultiByteToWideChar(CP_UTF8, 0, tmp, -1, wc, length);
				SetDlgItemTextW(hwnd, IDC_STRING, wc);

				SetWindowText(hwnd, Translate("Edit UNICODE value"));
				SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
			}
			break;
		case DBVT_BLOB:
		{
			ShowWindow(GetDlgItem(hwnd, IDC_STRING), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, IDC_SETTINGVALUE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, IDC_BLOB), SW_SHOW);

			if (!((struct DBsetting*)lParam)->setting[0])
			{
				SetWindowText(hwnd, Translate("New BLOB value"));
			}
			else
			{
				int j;
				char tmp[16];
				int len = ((struct DBsetting*)lParam)->dbv.cpbVal;
				char *data = (char*)_alloca(3 * (len + 1) + 10);
				BYTE *p = ((struct DBsetting*)lParam)->dbv.pbVal;

				if (!data) return TRUE;
				data[0] = '\0';

				for (j = 0; j < len; j++)
				{
					mir_snprintf(tmp, SIZEOF(tmp), "%02X ", (BYTE)p[j]);
					strcat(data, tmp);
				}

				SetWindowText(hwnd, Translate("Edit BLOB value"));
				SetDlgItemText(hwnd, IDC_SETTINGNAME, ((struct DBsetting*)lParam)->setting);
				SetDlgItemText(hwnd, IDC_BLOB, data);
			}
			ShowWindow(GetDlgItem(hwnd, CHK_HEX), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_DECIMAL), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, GRP_BASE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, GRP_TYPE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_BYTE), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_WORD), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_DWORD), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, CHK_STRING), SW_HIDE);
		}
		break;
		default: return TRUE;
		}
		TranslateDialogDefault(hwnd);
	}
	return TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case CHK_BYTE:
		case CHK_WORD:
		case CHK_DWORD:
			EnableWindow(GetDlgItem(hwnd, CHK_HEX), 1);
			EnableWindow(GetDlgItem(hwnd, CHK_DECIMAL), 1);
			CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, LOWORD(wParam));
			break;
		case CHK_STRING:
			EnableWindow(GetDlgItem(hwnd, CHK_HEX), 0);
			EnableWindow(GetDlgItem(hwnd, CHK_DECIMAL), 0);
			CheckRadioButton(hwnd, CHK_BYTE, CHK_STRING, LOWORD(wParam));
			break;

		case CHK_HEX:
		case CHK_DECIMAL:
			CheckRadioButton(hwnd, CHK_HEX, CHK_DECIMAL, LOWORD(wParam));
			{
				char *setting, temp[32];
				int settingLength, tmp;
				settingLength = GetWindowTextLength(GetDlgItem(hwnd, IDC_SETTINGVALUE));
				if (settingLength)
				{
					setting = (char*)_alloca(settingLength + 1);
					if (setting)
					{
						// havta convert it with mir_snprintf()
						GetDlgItemText(hwnd, IDC_SETTINGVALUE, setting, settingLength + 1);
						if (LOWORD(wParam) == CHK_DECIMAL && IsDlgButtonChecked(hwnd, CHK_DECIMAL))
						{
							sscanf(setting, "%X", &tmp);
							mir_snprintf(temp, SIZEOF(temp), "%ld", tmp);
						}
						else
						{
							sscanf(setting, "%d", &tmp);
							mir_snprintf(temp, SIZEOF(temp), "%X", tmp);
						}
						SetDlgItemText(hwnd, IDC_SETTINGVALUE, temp);
					}
				}
			}
			break;
		case IDOK:
		{
			struct DBsetting *dbsetting = (struct DBsetting*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
			char *setting, *value;
			int settingLength, valueLength, valueID = IDC_SETTINGVALUE;
			settingLength = GetWindowTextLength(GetDlgItem(hwnd, IDC_SETTINGNAME));

			if (IsWindowVisible(GetDlgItem(hwnd, IDC_STRING)))
				valueID = IDC_STRING;
			else
				if (IsWindowVisible(GetDlgItem(hwnd, IDC_SETTINGVALUE)))
					valueID = IDC_SETTINGVALUE;
				else
					if (IsWindowVisible(GetDlgItem(hwnd, IDC_BLOB)))
						valueID = IDC_BLOB;
					else
						break;

			valueLength = GetWindowTextLength(GetDlgItem(hwnd, valueID));

			if (dbsetting->dbv.type == DBVT_UTF8)
				valueLength *= sizeof(WCHAR);

			if (settingLength)
			{
				int settingValue;
				setting = (char*)_alloca(settingLength + 1);

				if (valueLength)
					value = (char*)_alloca(valueLength + 2);
				else
					value = (char*)_alloca(2);

				if (!setting || !value)
				{
					msg(Translate("Couldn't allocate enough memory!"), modFullname);
					DestroyWindow(hwnd);
					break;
				}

				GetDlgItemText(hwnd, IDC_SETTINGNAME, setting, settingLength + 1);

				if (valueLength)
				{
					if (dbsetting->dbv.type == DBVT_UTF8)
						GetDlgItemTextW(hwnd, valueID, (LPWSTR)value, (valueLength + 2));
					else
						GetDlgItemText(hwnd, valueID, value, valueLength + 1);
				}
				else
					if (IsWindowVisible(GetDlgItem(hwnd, IDC_STRING)) || (saveAsType(hwnd) == 3))
						memcpy(value, "\0\0", 2);
					else
						strcpy(value, "0");

				// delete the old setting
				if (mir_strcmp(setting, dbsetting->setting) && dbsetting->setting && (dbsetting->setting)[0] != 0)
					db_unset(dbsetting->hContact, dbsetting->module, dbsetting->setting);

				// delete the setting if we are saving as a different type
				switch (dbsetting->dbv.type)
				{
				case DBVT_BYTE:
					if (saveAsType(hwnd) != 0) db_unset(dbsetting->hContact, dbsetting->module, setting);
					break;
				case DBVT_WORD:
					if (saveAsType(hwnd) != 1) db_unset(dbsetting->hContact, dbsetting->module, setting);
					break;
				case DBVT_DWORD:
					if (saveAsType(hwnd) != 2) db_unset(dbsetting->hContact, dbsetting->module, setting);
					break;
					//case DBVT_ASCIIZ:
					//db_set_s(dbsetting->hContact, dbsetting->module, setting, value);
					//break;
				}
				// write the setting
				switch (saveAsType(hwnd))
				{
				case 0:
					if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue);
					else sscanf(value, "%d", &settingValue);
					db_set_b(dbsetting->hContact, dbsetting->module, setting, (BYTE)settingValue);
					break;
				case 1:
					if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue);
					else sscanf(value, "%d", &settingValue);
					db_set_w(dbsetting->hContact, dbsetting->module, setting, (WORD)settingValue);
					break;
				case 2:
					if (IsDlgButtonChecked(hwnd, CHK_HEX)) sscanf(value, "%x", &settingValue);
					else sscanf(value, "%d", &settingValue);
					db_set_dw(dbsetting->hContact, dbsetting->module, setting, (DWORD)settingValue);
					break;
				case 3:
					if (dbsetting->dbv.type == DBVT_UTF8)
						db_set_ws(dbsetting->hContact, dbsetting->module, setting, (WCHAR*)value);
					else if (dbsetting->dbv.type == DBVT_BLOB)
						WriteBlobFromString(dbsetting->hContact, dbsetting->module, setting, value, valueLength);
					else if (dbsetting->dbv.type == DBVT_ASCIIZ)
						db_set_s(dbsetting->hContact, dbsetting->module, setting, value);
					break;
				}

			}
		} // fall through
		case IDCANCEL:
		{
			struct DBsetting *dbsetting = (struct DBsetting*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
			mir_free(dbsetting->module);
			mir_free(dbsetting->setting);
			mir_free(dbsetting);
			DestroyWindow(hwnd);
		}
		break;
		}
		break;
	}
	return 0;
}
Beispiel #19
0
int CMraProto::MraDbSettingChanged(WPARAM hContact, LPARAM lParam)
{
	if (!m_bLoggedIn || !lParam || !hContact)
		return 0;

	DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;

	// это наш контакт, он не временный (есть в списке на сервере) и его обновление разрешено
	if (IsContactMra(hContact) && !db_get_b(hContact, "CList", "NotOnList", 0) && getDword(hContact, "HooksLocked", FALSE) == FALSE) {
		if (!strcmp(cws->szModule, "CList")) {
			// MyHandle setting
			if (!strcmp(cws->szSetting, "MyHandle")) {
				// always store custom nick
				CMStringW wszNick;
				if (cws->value.type == DBVT_DELETED) {
					wszNick = GetContactNameW(hContact);
					db_set_ws(hContact, "CList", "MyHandle", wszNick);
				}
				else if (cws->value.pszVal) {
					switch (cws->value.type) {
					case DBVT_WCHAR:
						wszNick = cws->value.pwszVal;
						break;
					case DBVT_UTF8:
						wszNick = ptrW(mir_utf8decodeW(cws->value.pszVal));
						break;
					case DBVT_ASCIIZ:
						wszNick = ptrW(mir_a2u_cp(cws->value.pszVal, MRA_CODE_PAGE));
						break;
					}
					if (wszNick.GetLength())
						MraModifyContact(hContact, 0, 0, 0, 0, &wszNick);
				}
			}
			// Group setting
			else if (!strcmp(cws->szSetting, "Group")) {
				CMStringW wszGroup;
				// manage group on server
				switch (cws->value.type) {
				case DBVT_WCHAR:
					wszGroup = cws->value.pwszVal;
					break;
				case DBVT_UTF8:
					wszGroup = ptrW(mir_utf8decodeW(cws->value.pszVal));
					break;
				case DBVT_ASCIIZ:
					wszGroup = ptrW(mir_a2u_cp(cws->value.pszVal, MRA_CODE_PAGE));
					break;
				}
				if (wszGroup.GetLength()) {
					DWORD dwGroupID = getDword(hContact, "GroupID", -1);
					if (dwGroupID != -1)
						MraMoveContactToGroup(hContact, dwGroupID, wszGroup);
				}
			}
			// NotOnList setting. Has a temporary contact just been added permanently?
			else if (!strcmp(cws->szSetting, "NotOnList")) {
				if (cws->value.type == DBVT_DELETED || (cws->value.type == DBVT_BYTE && cws->value.bVal == 0)) {
					CMStringW wszAuthMessage;
					if (!mraGetStringW(NULL, "AuthMessage", wszAuthMessage))
						wszAuthMessage = TranslateT(MRA_DEFAULT_AUTH_MESSAGE);

					db_unset(hContact, "CList", "Hidden");

					CMStringA szEmail, szPhones;
					CMStringW wszNick;
					DWORD dwGroupID, dwContactFlag;
					GetContactBasicInfoW(hContact, NULL, &dwGroupID, &dwContactFlag, NULL, NULL, &szEmail, &wszNick, &szPhones);
					MraAddContact(hContact, dwContactFlag, dwGroupID, szEmail, wszNick, &szPhones, &wszAuthMessage);
				}
			}
			// Hidden setting
			else if (!strcmp(cws->szSetting, "Hidden")) {
				DWORD dwContactFlag = GetContactFlags(hContact);
				if (cws->value.type == DBVT_DELETED || (cws->value.type == DBVT_BYTE && cws->value.bVal == 0))
					dwContactFlag &= ~CONTACT_FLAG_SHADOW;
				else
					dwContactFlag |= CONTACT_FLAG_SHADOW;

				MraModifyContact(hContact, 0, &dwContactFlag);
			}
		}
		// Ignore section
		else if (!strcmp(cws->szModule, "Ignore")) {
			if (!strcmp(cws->szSetting, "Mask1")) {
				DWORD dwContactFlag = GetContactFlags(hContact);
				if (cws->value.type == DBVT_DELETED || (cws->value.type == DBVT_DWORD && cws->value.dVal&IGNOREEVENT_MESSAGE) == 0)
					dwContactFlag &= ~CONTACT_FLAG_IGNORE;
				else
					dwContactFlag |= CONTACT_FLAG_IGNORE;

				MraModifyContact(hContact, 0, &dwContactFlag);
			}
		}
		// User info section
		else if (!strcmp(cws->szModule, "UserInfo")) {
			if (!strcmp(cws->szSetting, "MyPhone0") || !strcmp(cws->szSetting, "MyPhone1") || !strcmp(cws->szSetting, "MyPhone2"))
				MraModifyContact(hContact);
		}
	}
	return 0;
}
Beispiel #20
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;
}
Beispiel #21
0
INT_PTR CALLBACK DlgProcOptionsPage(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
	case WM_INITDIALOG:
		{
			char key[64];
			int count = 0;
			CMString replies;

			TranslateDialogDefault(hwndDlg);
			variables_skin_helpbutton(hwndDlg, IDC_VARIABLES);
			ShowWindow(GetDlgItem(hwndDlg, IDC_VARIABLES_HINT), ServiceExists(MS_VARS_FORMATSTRING));

			mir_subclassWindow(GetDlgItem(hwndDlg, IDC_REPLIES), MessageEditSubclassProc);

			mir_snprintf(key, _countof(key), "ImmediatelySend_%x", iNumber);
			CheckDlgButton(hwndDlg, IDC_IMMEDIATELY, db_get_w(NULL, MODULE, key, 1) ? BST_CHECKED : BST_UNCHECKED);

			mir_snprintf(key, _countof(key), "RepliesCount_%x", iNumber);
			count = db_get_w(NULL, MODULE, key, 0);

			for (int i = 0; i < count; i++)
			{
				mir_snprintf(key, _countof(key), "Reply_%x_%x", iNumber, i);
				wchar_t *value = db_get_wsa(NULL, MODULE, key);
				if (value)
				{
					replies.Append(value);
					replies.Append(_T("\r\n"));
				}
				mir_free(value);
			}
			SetDlgItemText(hwndDlg, IDC_REPLIES, replies.GetBuffer());
		}
		return TRUE;

	case WM_COMMAND:
		if (HIWORD(wParam) == BN_CLICKED) {
			switch(LOWORD(wParam)) {
			case IDC_VARIABLES:
				variables_showhelp(hwndDlg, IDC_REPLIES, VHF_SIMPLEDLG, NULL, NULL);
				break;

			case IDC_IMMEDIATELY:
				SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
				break;
			}
		}
		break;

	case WM_NOTIFY:
		{
			NMHDR *p = ((LPNMHDR)lParam);

			switch (p->code) {
			case PSN_APPLY:
				{
					char key[64];
					int count = 0;
					wchar_t *tszReplies;

					mir_snprintf(key, _countof(key), "RepliesCount_%x", iNumber);
					count = db_get_b(NULL, MODULE, key, 0);

					for (int i = 0; i < count; i++)
					{
						mir_snprintf(key, _countof(key), "Reply_%x_%x", iNumber, i);
						db_unset(NULL, MODULE, key);
					}

					int length = SendDlgItemMessage(hwndDlg, IDC_REPLIES, WM_GETTEXTLENGTH, 0, 0);
					tszReplies = (wchar_t*)mir_alloc(sizeof(wchar_t)* (length + 1));
					GetDlgItemText(hwndDlg, IDC_REPLIES, tszReplies, length + 1);
					tszReplies[length] = '\0';
					{
						CMString replies = tszReplies;
						if (replies.Right(2) != _T("\r\n"))
							replies.Append(_T("\r\n"));

						count = 0;
						int pos = -1, prev = 0;
						while ((pos = replies.Find(_T("\r\n"), prev)) != -1)
						{
							mir_snprintf(key, _countof(key), "Reply_%x_%x", iNumber, count++);
							db_set_ws(NULL, MODULE, key, replies.Mid(prev, pos - prev).GetBuffer());
							prev = pos + 2;
						}
					}
					mir_free(tszReplies);

					mir_snprintf(key, _countof(key), "RepliesCount_%x", iNumber);
					db_set_w(NULL, MODULE, key, count);

					mir_snprintf(key, _countof(key), "ImmediatelySend_%x", iNumber);
					db_set_b(NULL, MODULE, key, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_IMMEDIATELY));

					return TRUE;
				}
				break;
			}
		}
		break;
	}

	if (HIWORD(wParam) == EN_CHANGE && GetFocus() == (HWND)lParam)
		SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);

	return FALSE;
}
Beispiel #22
0
bool TwitterProto::NegotiateConnection()
{
	debugLogA( _T("***** Negotiating connection with Twitter"));
	disconnectionCount = 0;

	// saving the current status to a temp var
	int old_status = m_iStatus;
	DBVARIANT dbv;

	wstring oauthToken;
	wstring oauthTokenSecret;	
	wstring oauthAccessToken;
	wstring oauthAccessTokenSecret;
	string screenName;

	INT_PTR dbTOK = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK,&dbv);
	if (!dbTOK) {
		oauthToken = dbv.pwszVal;
		db_free(&dbv);
		//debugLogW("**NegotiateConnection - we have an oauthToken already in the db - %s", oauthToken);
	}
 
	INT_PTR dbTOKSec = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK_SECRET,&dbv);
	if (!dbTOKSec) {
		oauthTokenSecret = dbv.pwszVal;
		db_free(&dbv);
		//debugLogW("**NegotiateConnection - we have an oauthTokenSecret already in the db - %s", oauthTokenSecret);
	}

	INT_PTR dbName = db_get_s(0,m_szModuleName,TWITTER_KEY_NICK,&dbv);
	if (!dbName) {
		screenName = dbv.pszVal;
		db_free(&dbv);
		//debugLogW("**NegotiateConnection - we have a username already in the db - %s", screenName);
	}
	else {
		dbName = db_get_s(0,m_szModuleName,TWITTER_KEY_UN,&dbv);
		if (!dbName) {
			screenName = dbv.pszVal;
			db_set_s(0,m_szModuleName,TWITTER_KEY_NICK,dbv.pszVal);
			db_free(&dbv);
			//debugLogW("**NegotiateConnection - we have a username already in the db - %s", screenName);
		}
	}

 	// twitter changed the base URL in v1.1 of the API, I don't think users will need to modify it, so
	// i'll be forcing it to the new API URL here. After a while I can get rid of this as users will
	// have either had this run at least once, or have reset their miranda profile. 14/10/2012
	if(db_get_b(0,m_szModuleName,"UpgradeBaseURL",1)) {
		db_set_s(0,m_szModuleName,TWITTER_KEY_BASEURL,"https://api.twitter.com/");
		db_set_b(0,m_szModuleName,"UpgradeBaseURL",0);
	}

	if((oauthToken.size() <= 1) || (oauthTokenSecret.size() <= 1)) {
		// first, reset all the keys so we can start fresh
		resetOAuthKeys();
		debugLogA( _T("**NegotiateConnection - Reset OAuth Keys"));

		//twit_.set_credentials(ConsumerKey, ConsumerSecret, oauthAccessToken, oauthAccessTokenSecret, L"", false);
		// i think i was doin the wrong thing here.. i was setting the credentials as oauthAccessToken instead of oauthToken
		// have to test..
		debugLogA( _T("**NegotiateConnection - Setting Consumer Keys..."));
		/*debugLogW("**NegotiateConnection - sending set_cred: consumerKey is %s", ConsumerKey);
		debugLogW("**NegotiateConnection - sending set_cred: consumerSecret is %s", ConsumerSecret);
		debugLogW("**NegotiateConnection - sending set_cred: oauthToken is %s", oauthToken);
		debugLogW("**NegotiateConnection - sending set_cred: oauthTokenSecret is %s", oauthTokenSecret);
		debugLogA("**NegotiateConnection - sending set_cred: no pin");*/
		twit_.set_credentials("", ConsumerKey, ConsumerSecret, oauthToken, oauthTokenSecret, L"", false);
		debugLogA( _T("**NegotiateConnection - Requesting oauthTokens"));
		http::response resp = twit_.request_token();

		//wstring rdata_WSTR(resp.data.length(),L' ');
		//std::copy(resp.data.begin(), resp.data.end(), rdata_WSTR.begin());
		wstring rdata_WSTR = UTF8ToWide(resp.data);

		//debugLogW("**NegotiateConnection - REQUEST TOKEN IS %s", rdata_WSTR);
		OAuthParameters response = twit_.ParseQueryString(rdata_WSTR);
		oauthToken = response[L"oauth_token"];
		oauthTokenSecret = response[L"oauth_token_secret"];
		//debugLogW("**NegotiateConnection - oauthToken is %s", oauthToken);
		//debugLogW("**NegotiateConnection - oauthTokenSecret is %s", oauthTokenSecret);

		if (oauthToken.length() < 1) {
			ShowPopup("OAuth Tokens not received, check your internet connection?", 1);
			debugLogA( _T("**NegotiateConnection - OAuth tokens not received, stopping before we open the web browser.."));
			return false;
		}

		//write those bitches to the db foe latta
		db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK,oauthToken.c_str());
		db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK_SECRET,oauthTokenSecret.c_str());
		
		// this looks like bad code.. can someone clean this up please?  or confirm that it's ok
		wchar_t buf[1024] = {};
		mir_snwprintf(buf, SIZEOF(buf), AuthorizeUrl.c_str(), oauthToken.c_str());

		debugLogW( _T("**NegotiateConnection - Launching %s"), buf);
		ShellExecute(NULL, L"open", buf, NULL, NULL, SW_SHOWNORMAL);
		
		ShowPinDialog();
	}

	if (!db_get_ts(NULL,m_szModuleName,TWITTER_KEY_GROUP,&dbv)) {
		CallService(MS_CLIST_GROUPCREATE, 0, (LPARAM)dbv.ptszVal );
		db_free(&dbv);	
	}

	bool realAccessTok = false;
	bool realAccessTokSecret = false;

	// remember, dbTOK is 0 (false) if the db setting has returned something
	dbTOK = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK,&dbv);
	if (!dbTOK) { 
		oauthAccessToken = dbv.pwszVal;
		db_free(&dbv);
		// this bit is saying "if we have found the db key, but it contains no data, then set dbTOK to 1"
		if (oauthAccessToken.size() > 1) { 
			realAccessTok = true; 
			//debugLogW("**NegotiateConnection - we have an oauthAccessToken already in the db - %s", oauthAccessToken); 
		}
		else { debugLogA( _T("**NegotiateConnection - oauthAccesToken too small? this is.. weird.")); }
	}

	dbTOKSec = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK_SECRET,&dbv);
	if (!dbTOKSec) { 
		oauthAccessTokenSecret = dbv.pwszVal;
		db_free(&dbv);
		if (oauthAccessTokenSecret.size() > 1) { 
			realAccessTokSecret = true; 
			//debugLogW("**NegotiateConnection - we have an oauthAccessTokenSecret already in the db - %s", oauthAccessTokenSecret); 
		}
		else { debugLogA( _T("**NegotiateConnection - oauthAccessTokenSecret too small? weird")); }
	}

	if (!realAccessTok || !realAccessTokSecret) {  // if we don't have one of these beasties then lets go get 'em!
		wstring pin;
		debugLogA( _T("**NegotiateConnection - either the accessToken or accessTokenSecret was not there.."));
		if (!db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_PIN,&dbv)) {
			pin = dbv.pwszVal;
			//debugLogW("**NegotiateConnection - we have an pin already in the db - %s", pin);
			db_free(&dbv);
		}
		else {
			ShowPopup(TranslateT("OAuth variables are out of sequence, they have been reset. Please reconnect and reauthorize Miranda to Twitter.com (do the PIN stuff again)"));
			debugLogA( _T("**NegotiateConnection - We don't have a PIN?  this doesn't make sense.  Resetting OAuth keys and setting offline."));
			resetOAuthKeys();

			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_FAILED,(HANDLE)old_status,m_iStatus);

			// Set to offline
			old_status = m_iStatus;
			m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);

			return false;
		}

		debugLogA( _T("**NegotiateConnection - Setting Consumer Keys and PIN..."));
		/*debugLogW("**NegotiateConnection - sending set_cred: consumerKey is %s", ConsumerKey);
		debugLogW("**NegotiateConnection - sending set_cred: consumerSecret is %s", ConsumerSecret);
		debugLogW("**NegotiateConnection - sending set_cred: oauthToken is %s", oauthToken);
		debugLogW("**NegotiateConnection - sending set_cred: oauthTokenSecret is %s", oauthTokenSecret);
		debugLogW("**NegotiateConnection - sending set_cred: pin is %s", pin);*/

		twit_.set_credentials("", ConsumerKey, ConsumerSecret, oauthToken, oauthTokenSecret, pin, false);

		debugLogA( _T("**NegotiateConnection - requesting access tokens..."));
		http::response accessResp = twit_.request_access_tokens();
		if (accessResp.code != 200) {
			debugLogA( _T("**NegotiateConnection - Failed to get Access Tokens, HTTP response code is: %d"), accessResp.code);
			ShowPopup(TranslateT("Failed to get Twitter Access Tokens, please go offline and try again. If this keeps happening, check your internet connection."));

			resetOAuthKeys();

			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_FAILED,(HANDLE)old_status,m_iStatus);

			// Set to offline
			old_status = m_iStatus;
			m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);

			return false;
		}
		else {
			debugLogA( _T("**NegotiateConnection - Successfully retrieved Access Tokens"));

			wstring rdata_WSTR2 = UTF8ToWide(accessResp.data);
			//debugLogW("**NegotiateConnection - accessToken STring is %s", rdata_WSTR2);
		
			OAuthParameters accessTokenParameters = twit_.ParseQueryString(rdata_WSTR2);

			oauthAccessToken = accessTokenParameters[L"oauth_token"];
			//debugLogW("**NegotiateConnection - oauthAccessToken is %s", oauthAccessToken);

			oauthAccessTokenSecret = accessTokenParameters[L"oauth_token_secret"];
			//debugLogW("**NegotiateConnection - oauthAccessTokenSecret is %s", oauthAccessTokenSecret);

			screenName = WideToUTF8(accessTokenParameters[L"screen_name"]);
			debugLogA( _T("**NegotiateConnection - screen name is %s"), screenName.c_str());
	
			//save em
			db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK,oauthAccessToken.c_str());
			db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK_SECRET,oauthAccessTokenSecret.c_str());
			db_set_s(0,m_szModuleName,TWITTER_KEY_NICK,screenName.c_str());
			db_set_s(0,m_szModuleName,TWITTER_KEY_UN,screenName.c_str());
		}
	}

/*	if( !db_get_s(0,m_szModuleName,TWITTER_KEY_PASS,&dbv)) {
		CallService(MS_DB_CRYPT_DECODESTRING,strlen(dbv.pszVal)+1,
			reinterpret_cast<LPARAM>(dbv.pszVal));
		pass = dbv.pszVal;
		db_free(&dbv);
	}
	else {
		ShowPopup(TranslateT("Please enter a password."));
		return false;
	}*/

	if( !db_get_s(0,m_szModuleName,TWITTER_KEY_BASEURL,&dbv))
	{
		ScopedLock s(twitter_lock_);
		twit_.set_base_url(dbv.pszVal);
		db_free(&dbv);
	}

	debugLogA( _T("**NegotiateConnection - Setting Consumer Keys and verifying creds..."));
	/*debugLogW("**NegotiateConnection - sending set_cred: consumerKey is %s", ConsumerKey);
	debugLogW("**NegotiateConnection - sending set_cred: consumerSecret is %s", ConsumerSecret);
	debugLogW("**NegotiateConnection - sending set_cred: oauthAccessToken is %s", oauthAccessToken);
	debugLogW("**NegotiateConnection - sending set_cred: oauthAccessTokenSecret is %s", oauthAccessTokenSecret);
	debugLogA("**NegotiateConnection - sending set_cred: no pin");*/

	if (screenName.empty()) {
		ShowPopup(TranslateT("You're missing the Nick key in the database. This isn't really a big deal, but you'll notice some minor quirks (self contact in list, no group chat outgoing message highlighting, etc). To fix it either add it manually or reset your Twitter account in the Miranda account options"));
		debugLogA( _T("**NegotiateConnection - Missing the Nick key in the database.  Everything will still work, but it's nice to have"));
	}

	bool success;
	{		
		ScopedLock s(twitter_lock_);

		success = twit_.set_credentials(screenName, ConsumerKey, ConsumerSecret, oauthAccessToken, oauthAccessTokenSecret, L"", true);
	}

	if(!success) {
		//ShowPopup(TranslateT("Something went wrong with authorisation, OAuth keys have been reset.  Please try to reconnect.  If problems persist, please se your doctor"));
		debugLogA( _T("**NegotiateConnection - Verifying credentials failed!  No internet maybe?"));

		//resetOAuthKeys();
		ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_FAILED,(HANDLE)old_status,m_iStatus);

		// Set to offline
		old_status = m_iStatus;
		m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
		ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);

		return false;
	}
	else {
		m_iStatus = m_iDesiredStatus;

		ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);
		return true;
	}
}
Beispiel #23
0
void __cdecl FindSettings(LPVOID param)
{
	FindInfo* fi = (FindInfo*)param;
	HWND hwndParent = GetParent(fi->hwnd);

	ModuleSettingLL ModuleList, SettingList;
	ModSetLinkLinkItem *module, *setting;

	MCONTACT hContact;
	DBVARIANT dbv = { 0 };

	int foundCount = 0,	 replaceCount = 0, deleteCount = 0;

	DWORD numsearch = 0, numreplace = 0;
	int NULLContactDone = 0;

	if (!fi->search || !EnumModules(&ModuleList)) {
		fi_free(fi);
		return;
	}

	_T2A search(fi->search);
	_T2A replace(fi->replace);

    // skip modules and setting names on unicode search or replace
   	if (IsRealUnicode(fi->search) || IsRealUnicode(fi->replace)) {
   		fi->options &= ~(F_SETNAME | F_MODNAME); 
   		fi->options |= F_UNICODE;
   	}

    if (!(fi->options & F_UNICODE) && (fi->options & F_SETVAL)) {
		char val[16];
		numsearch = strtoul(search, NULL, 10);
		_ultoa(numsearch, val, 10);
		if (!mir_strcmp(search, val)) {
			fi->options |= F_NUMSRCH;
			// replace numeric values only entirely
			if (replace && (fi->options & F_ENTIRE)) {
				numreplace = strtoul(replace, NULL, 10);
				_ultoa(numreplace, val, 10);
				if (!replace[0] || !mir_strcmp(replace, val))
					fi->options |= F_NUMREPL;
			}
		}
	}

	SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)TranslateT("Searching..."));

	hContact = 0;

	while (GetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA)) {

		if (!hContact) {
			if (NULLContactDone) 
				break;
			else {
				NULLContactDone = 1;
				hContact = db_find_first();
			}
		}
		else 
			hContact = db_find_next(hContact);

		for (module = ModuleList.first; module; module = module->next) {

			if (IsModuleEmpty(hContact, module->name))
				continue;

			if (fi->options & (F_SETVAL | F_SETNAME)) {

				if (!EnumSettings(hContact, module->name, &SettingList)) {
					fi_free(fi);
					FreeModuleSettingLL(&ModuleList);
					return;
				}

				for (setting = SettingList.first; setting; setting = setting->next) {

					dbv.type = 0;
					if (db_get_s(hContact, module->name, setting->name, &dbv, 0))
						continue;

					// check in settings value				
					if (fi->options & F_SETVAL) {

						TCHAR *value = NULL;

					    switch(dbv.type) {

						case DBVT_BYTE: 
						case DBVT_WORD: 
						case DBVT_DWORD:
							if ((fi->options & F_NUMSRCH) && numsearch == getNumericValue(&dbv)) {
								TCHAR *val = fi->search;
								int flag = F_SETVAL;

								if (fi->options & F_NUMREPL) {
								    if (replace[0]) {
										db_unset(hContact, module->name, setting->name);
										flag |= F_DELETED;
										deleteCount++;
									} 
									else
									if (setNumericValue(hContact, module->name, setting->name, numreplace, dbv.type)) {
										val = fi->replace;
										flag |= F_REPLACED;
										replaceCount++;
									}
								}

								ItemFound(fi->hwnd, hContact, module->name, setting->name, val, flag);
							}
							break;

						case DBVT_WCHAR:
							if (!value) value = mir_u2t(dbv.pwszVal);
						case DBVT_UTF8:
							if (!value) value = mir_utf8decodeT(dbv.pszVal);
						case DBVT_ASCIIZ:
							if (!value) value = mir_a2t(dbv.pszVal);

							if (FindMatchT(value, fi->search, fi->options)) {
								foundCount++;
								ptrT ptr;
								TCHAR *newValue = value;
								int flag = F_SETVAL;

								if (fi->replace) {
									newValue = (fi->options & F_ENTIRE) ? fi->replace : ptr = multiReplaceT(value, fi->search, fi->replace, fi->options & F_CASE);
									// !!!! delete or make empty ?
									if (!newValue[0]) {
										db_unset(hContact, module->name, setting->name);
										flag |= F_DELETED;
										newValue = value;
										deleteCount++;
									} else {
#ifdef _UNICODE
                                        // save as unicode if needed
										if (dbv.type != DBVT_ASCIIZ || IsRealUnicode(newValue))
											db_set_ws(hContact, module->name, setting->name, newValue);
										else												
#endif
											db_set_s(hContact, module->name, setting->name, _T2A(newValue)); 
										flag |= F_REPLACED;
										replaceCount++;
									}
								}

								ItemFound(fi->hwnd, hContact, module->name, setting->name, newValue, flag);
							}
							mir_free(value);
							break;
						} // switch
					}

					// check in setting name
					if ((fi->options & F_SETNAME) && FindMatchA(setting->name, search, fi->options)) {
						foundCount++;
						ptrA ptr;
						char *newSetting = setting->name;
						int flag = F_SETNAME;

						if (replace) {
							newSetting = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(setting->name, search, replace, fi->options & F_CASE);

							if (!newSetting[0]) {
								db_unset(hContact, module->name, setting->name);
								flag |= F_DELETED;
								newSetting = setting->name;
								deleteCount++;
							} else {
								DBVARIANT dbv2;
								// skip if exist
								if (!db_get_s(hContact, module->name, newSetting, &dbv2, 0)) 
									db_free(&dbv2);
								else if (!db_set(hContact, module->name, newSetting, &dbv)) {
									db_unset(hContact, module->name, setting->name);
									flag |= F_REPLACED;
							 		replaceCount++;
								}
							}
						}

						ItemFound(fi->hwnd, hContact, module->name, newSetting, NULL, flag);
					}

					db_free(&dbv);

				} // for(setting)

				FreeModuleSettingLL(&SettingList);
			}

			// check in module name
			if ((fi->options & F_MODNAME) && FindMatchA(module->name, search, fi->options)) {
				foundCount++;
				char *newModule = module->name;
				int flag = F_MODNAME;
				ptrA ptr;

				if (replace) {
					newModule = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(module->name, search, replace, fi->options & F_CASE);
								
					if (!newModule[0]) {
						deleteModule(hContact, module->name, 0);
						replaceTreeItem(hContact, module->name, NULL);
						flag |= F_DELETED;
						newModule = module->name;
						deleteCount++;
					} 
					else if (renameModule(hContact, module->name, newModule)) {
   						replaceTreeItem(hContact, module->name, NULL);
						flag |= F_REPLACED;
						replaceCount++;
					}
				}

				ItemFound(fi->hwnd, hContact, newModule, 0, 0, flag);
			}

		} // for(module)
	}

	TCHAR msg[MSG_SIZE];	
	mir_sntprintf(msg, TranslateT("Finished. Items found: %d / replaced: %d / deleted: %d"), foundCount, replaceCount, deleteCount);
	SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)msg);

	if (fi->replace) {
		EnableWindow(GetDlgItem(hwndParent, IDC_SEARCH), 1);
		SetDlgItemText(hwndParent, IDOK, TranslateT("&Replace"));
	}
	else {
		SetDlgItemText(hwndParent, IDC_SEARCH, TranslateT("&Search"));
		EnableWindow(GetDlgItem(hwndParent, IDOK), 1);
	}

	fi_free(fi);
	FreeModuleSettingLL(&ModuleList);

	SetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA, 0);
	EnableWindow(GetDlgItem(hwndParent, IDCANCEL), 1);
}
Beispiel #24
0
MIRANDA_HOOK_EVENT(ME_DB_EVENT_FILTER_ADD, w, l)
{
	MCONTACT hContact = (MCONTACT)w;
	if (!l) //fix potential DEP crash
		return 0;
	DBEVENTINFO * dbei = (DBEVENTINFO*)l;

	// if event is in protocol that is not despammed
	if (!ProtoInList(dbei->szModule)) {
		// ...let the event go its way
		return 0;
	}
	//do not check excluded contact

	if (db_get_b(hContact, pluginName, "Answered", 0))
		return 0;
	if (db_get_b(hContact, pluginName, "Excluded", 0)) {
		if (!db_get_b(hContact, "CList", "NotOnList", 0))
			db_unset(hContact, pluginName, "Excluded");
		return 0;
	}
	//we want block not only messages, i seen many types other eventtype flood
	if (dbei->flags & DBEF_READ)
		// ...let the event go its way
		return 0;
	//mark contact which we trying to contact for exclude from check
	if ((dbei->flags & DBEF_SENT) && db_get_b(hContact, "CList", "NotOnList", 0)
		&& (!gbMaxQuestCount || db_get_dw(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount) && gbExclude) {
		db_set_b(hContact, pluginName, "Excluded", 1);
		return 0;
	}
	// if message is from known or marked Answered contact
	if (!db_get_b(hContact, "CList", "NotOnList", 0))
		// ...let the event go its way
		return 0;
	// if message is corrupted or empty it cannot be an answer.
	if (!dbei->cbBlob || !dbei->pBlob)
		// reject processing of the event
		return 1;

	tstring message;

	if (dbei->flags & DBEF_UTF) {
		wchar_t* msg_u;
		char* msg_a = mir_strdup((char*)dbei->pBlob);
		mir_utf8decode(msg_a, &msg_u);
		message = msg_u;
	}
	else
		message = mir_a2u((char*)(dbei->pBlob));

	// if message contains right answer...

	boost::algorithm::erase_all(message, "\r");
	boost::algorithm::erase_all(message, "\n");

	bool bSendMsg = true;
	if (gbInvisDisable) {
		if (CallProtoService(dbei->szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE)
			bSendMsg = false;
		else if (db_get_w(hContact, dbei->szModule, "ApparentMode", 0) == ID_STATUS_OFFLINE)
			bSendMsg = false; //is it useful ?
	}
	bool answered = false;
	if (gbMathExpression) {
		if (boost::algorithm::all(message, boost::is_digit())) {
			int num = _ttoi(message.c_str());
			int math_answer = db_get_dw(hContact, pluginName, "MathAnswer", 0);
			if (num && math_answer)
				answered = (num == math_answer);
		}
	}
	else if (!gbRegexMatch)
		answered = gbCaseInsensitive ? (!Stricmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str()))) : (!mir_tstrcmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str())));
	else {
		if (gbCaseInsensitive) {
			std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message));
			boost::algorithm::to_upper(check);
			boost::algorithm::to_upper(msg);
			boost::regex expr(check);
			answered = boost::regex_search(msg.begin(), msg.end(), expr);
		}
		else {
			std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message));
			boost::regex expr(check);
			answered = boost::regex_search(msg.begin(), msg.end(), expr);
		}
	}
	if (answered) {
		// unhide contact
		db_unset(hContact, "CList", "Hidden");

		db_unset(hContact, pluginName, "MathAnswer");

		// mark contact as Answered
		db_set_b(hContact, pluginName, "Answered", 1);

		//add contact permanently
		if (gbAddPermanent) //do not use this )
			db_unset(hContact, "CList", "NotOnList");

		// send congratulation
		if (bSendMsg) {
			tstring prot = DBGetContactSettingStringPAN(NULL, dbei->szModule, "AM_BaseProto", _T(""));
			// for notICQ protocols or disable auto auth. reqwest
			if ((Stricmp(_T("ICQ"), prot.c_str())) || (!gbAutoReqAuth)) {
				char * buf = mir_utf8encodeW(variables_parse(gbCongratulation, hContact).c_str());
				CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)buf);
				mir_free(buf);
			}
			// Note: For ANSI can be not work
			if (!Stricmp(_T("ICQ"), prot.c_str())) {
				// grand auth.
				if (gbAutoAuth)
					CallProtoService(dbei->szModule, "/GrantAuth", w, 0);
				// add contact to server list and local group
				if (gbAutoAddToServerList) {
					db_set_ws(hContact, "CList", "Group", gbAutoAuthGroup.c_str());
					CallProtoService(dbei->szModule, "/AddServerContact", w, 0);
					db_unset(hContact, "CList", "NotOnList");
				};
				// auto auth. reqwest with send congratulation
				if (gbAutoReqAuth)
					CallContactService(hContact, PSS_AUTHREQUEST, 0, (LPARAM)variables_parse(gbCongratulation, hContact).c_str());
			}
		}
		return 0;
	}
	// URL contains check
	bSendMsg = (bSendMsg && gbIgnoreURL) ? (!IsUrlContains((TCHAR *)message.c_str())) : bSendMsg;
	// if message message does not contain infintite talk protection prefix
	// and question count for this contact is less then maximum
	if (bSendMsg) {
		if ((!gbInfTalkProtection || tstring::npos == message.find(_T("StopSpam automatic message:\r\n")))
			&& (!gbMaxQuestCount || db_get_dw(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount)) {
			// send question
			tstring q;
			if (gbInfTalkProtection)
				q += _T("StopSpam automatic message:\r\n");
			if (gbMathExpression) { //parse math expression in question
				tstring tmp_question = gbQuestion;
				std::list<int> args;
				std::list<TCHAR> actions;
				tstring::size_type p1 = gbQuestion.find(_T("X")), p2 = 0;
				const tstring expr_chars = _T("X+-/*"), expr_acts = _T("+-/*");
				while (p1 < gbQuestion.length() && p1 != tstring::npos && expr_chars.find(gbQuestion[p1]) != tstring::npos) {
					std::string arg;
					p2 = p1;
					for (p1 = gbQuestion.find(_T("X"), p1); (p1 < gbQuestion.length()) && (gbQuestion[p1] == L'X'); ++p1)
						arg += get_random_num(1);

					tmp_question.replace(p2, arg.size(), toUTF16(arg));
					args.push_back(atoi(arg.c_str()));

					if ((p1 < gbQuestion.length()) && (p1 != tstring::npos) && (expr_acts.find(gbQuestion[p1]) != tstring::npos))
						actions.push_back(gbQuestion[p1]);
					++p1;
				}
				int math_answer = 0;
				math_answer = args.front();
				args.pop_front();
				while (!args.empty()) {
					if (!actions.empty()) {
						switch (actions.front()) {
						case _T('+'):
							{
								math_answer += args.front();
								args.pop_front();
							}
							break;
						case _T('-'):
							{
								math_answer -= args.front();
								args.pop_front();
							}
							break;
						case _T('/'):
							{
								math_answer /= args.front();
								args.pop_front();
							}
							break;
						case _T('*'):
							{
								math_answer *= args.front();
								args.pop_front();
							}
							break;
						}
						actions.pop_front();
					}
					else
						break;
				}
				db_set_dw(hContact, pluginName, "MathAnswer", math_answer);
				q += variables_parse(tmp_question, hContact);
			}
			else
				q += variables_parse(gbQuestion, hContact);

			CallContactService(hContact, PSS_MESSAGE, 0, ptrA(mir_utf8encodeW(q.c_str())));

			// increment question count
			DWORD questCount = db_get_dw(hContact, pluginName, "QuestionCount", 0);
			db_set_dw(hContact, pluginName, "QuestionCount", questCount + 1);
		}
		else {
			if (gbIgnoreContacts)
				db_set_dw(hContact, "Ignore", "Mask1", 0x0000007F);
		}
	}
	if (gbHideContacts)
		db_set_b(hContact, "CList", "Hidden", 1);
	if (gbSpecialGroup)
		db_set_ws(hContact, "CList", "Group", gbSpammersGroup.c_str());
	db_set_b(hContact, "CList", "NotOnList", 1);

	// save first message from contact
	if (db_get_dw(hContact, pluginName, "QuestionCount", 0) < 2) {
		dbei->flags |= DBEF_READ;
		db_event_add(hContact, dbei);
	};
	// reject processing of the event
	LogSpamToFile(hContact, message);
	return 1;
}
Beispiel #25
0
void CDropbox::RequestAccountInfo()
{
	HttpRequest *request = new HttpRequest(hNetlibUser, REQUEST_GET, DROPBOX_API_URL "/account/info");
	request->AddBearerAuthHeader(db_get_sa(NULL, MODULE, "TokenSecret"));
	mir_ptr<NETLIBHTTPREQUEST> response(request->Send());

	delete request;

	MCONTACT hContact = CDropbox::GetDefaultContact();

	if (response && response->resultCode == HTTP_STATUS_OK)
	{
		JSONROOT root(response->pData);
		if (root)
		{
			JSONNODE *node = json_get(root, "referral_link");
			if (node)
			{
				ptrW referral_link = ptrW(json_as_string(node));
				db_set_ws(hContact, MODULE, "Homepage", referral_link);
			}

			node = json_get(root, "display_name");
			if (node)
			{
				ptrW display_name = ptrW(json_as_string(node));
				wchar_t *sep = wcsrchr(display_name, L' ');
				if (sep)
				{
					db_set_ws(hContact, MODULE, "LastName", sep + 1);
					display_name[wcslen(display_name) - wcslen(sep)] = '\0';
					db_set_ws(hContact, MODULE, "FirstName", display_name);
				}
				else
				{
					db_set_ws(hContact, MODULE, "FirstName", display_name);
					db_unset(hContact, MODULE, "LastName");
				}
			}

			node = json_get(root, "country");
			if (node)
			{
				ptrW isocodeW(json_as_string(node));
				ptrA isocode(mir_u2a(isocodeW));

				if (!strlen(isocode))
					db_unset(hContact, MODULE, "Country");
				else
				{
					char *country = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)isocode, 0);
					db_set_s(hContact, MODULE, "Country", country);
				}
			}

			node = json_get(root, "quota_info");
			JSONNODE *nroot = json_as_node(node);
			if (nroot)
			{
				node = json_get(nroot, "shared");
				if (node)
					db_set_dw(hContact, MODULE, "SharedQuota", json_as_int(node));
				node = json_get(nroot, "normal");
				if (node)
					db_set_dw(hContact, MODULE, "NormalQuota", json_as_int(node));
				node = json_get(nroot, "quota");
				if (node)
					db_set_dw(hContact, MODULE, "TotalQuota", json_as_int(node));
			}
		}
	}

	HandleHttpResponseError(hNetlibUser, response);
}
int ContactSettingChanged(WPARAM hContact, LPARAM lParam)
{
	DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
	if (strcmp(cws->szSetting, DB_MIRVER))
		return 0;

	SHOWPOPUP_DATA sd = { 0 };
	char *szProto = GetContactProto(hContact);
	if (g_PreviewOptPage)
		sd.MirVer = L"Miranda NG ICQ 0.93.5.3007";
	else {
		if (!hContact) // exit if hContact == NULL and it's not a popup preview
			return 0;

		_ASSERT(szProto);
		if (!strcmp(szProto, META_PROTO)) // workaround for metacontacts
			return 0;

		sd.MirVer = db_get_s(hContact, szProto, DB_MIRVER, L"");
		if (sd.MirVer.IsEmpty())
			return 0;
	}
	sd.OldMirVer = db_get_s(hContact, MODULENAME, DB_OLDMIRVER, L"");
	db_set_ws(hContact, MODULENAME, DB_OLDMIRVER, sd.MirVer); // we have to write it here, because we modify sd.OldMirVer and sd.MirVer to conform our settings later
	if (sd.OldMirVer.IsEmpty())  // looks like it's the right way to do
		return 0;

	COptPage PopupOptPage;
	if (g_PreviewOptPage)
		PopupOptPage = *g_PreviewOptPage;
	else {
		PopupOptPage = g_PopupOptPage;
		PopupOptPage.DBToMem();
	}

	MCONTACT hContactOrMeta = (hContact) ? db_mc_getMeta(hContact) : 0;
	if (!hContactOrMeta)
		hContactOrMeta = hContact;

	if (hContact && db_get_b(hContactOrMeta, "CList", "Hidden", 0))
		return 0;

	int PerContactSetting = hContact ? db_get_b(hContact, MODULENAME, DB_CCN_NOTIFY, NOTIFY_USEGLOBAL) : NOTIFY_ALWAYS; // NOTIFY_ALWAYS for preview
	if (PerContactSetting == NOTIFY_USEGLOBAL && hContactOrMeta != hContact) // subcontact setting has a priority over a metacontact setting
		PerContactSetting = db_get_b(hContactOrMeta, MODULENAME, DB_CCN_NOTIFY, NOTIFY_USEGLOBAL);

	if (PerContactSetting && (PerContactSetting == NOTIFY_ALMOST_ALWAYS || PerContactSetting == NOTIFY_ALWAYS || !PopupOptPage.GetValue(IDC_POPUPOPTDLG_USESTATUSNOTIFYFLAG) || !(db_get_dw(hContactOrMeta, "Ignore", "Mask1", 0) & 0x8))) { // check if we need to notify at all
		sd.hContact = hContact;
		sd.PopupOptPage = &PopupOptPage;
		if (!PopupOptPage.GetValue(IDC_POPUPOPTDLG_VERCHGNOTIFY) || !PopupOptPage.GetValue(IDC_POPUPOPTDLG_SHOWVER)) {
			if (bFingerprintExists) {
				LPCTSTR ptszOldClient = Finger_GetClientDescr(sd.OldMirVer);
				LPCTSTR ptszClient = Finger_GetClientDescr(sd.MirVer);
				if (ptszOldClient && ptszClient) {
					if (PerContactSetting != NOTIFY_ALMOST_ALWAYS && PerContactSetting != NOTIFY_ALWAYS && !PopupOptPage.GetValue(IDC_POPUPOPTDLG_VERCHGNOTIFY) && !wcscmp(ptszClient, ptszOldClient))
						return 0;

					if (!PopupOptPage.GetValue(IDC_POPUPOPTDLG_SHOWVER)) {
						sd.MirVer = ptszClient;
						sd.OldMirVer = ptszOldClient;
					}
				}
			}
		}
		if (sd.MirVer == (const wchar_t*)sd.OldMirVer) {
			_ASSERT(hContact);
			return 0;
		}
		if (PerContactSetting == NOTIFY_ALWAYS || (PopupOptPage.GetValue(IDC_POPUPOPTDLG_POPUPNOTIFY) && (g_PreviewOptPage || PerContactSetting == NOTIFY_ALMOST_ALWAYS || -1 == PcreCheck(sd.MirVer)))) {
			ShowPopup(&sd);
			Skin_PlaySound(CLIENTCHANGED_SOUND);
		}
	}

	if (hContact) {
		TCString ClientName;
		if (PopupOptPage.GetValue(IDC_POPUPOPTDLG_SHOWPREVCLIENT) && sd.OldMirVer.GetLen()) {
			mir_snwprintf(ClientName.GetBuffer(MAX_MSG_LEN), MAX_MSG_LEN, TranslateT("%s (was %s)"), (const wchar_t*)sd.MirVer, (const wchar_t*)sd.OldMirVer);
			ClientName.ReleaseBuffer();
		}
		else ClientName = sd.MirVer;
	}
	_ASSERT(sd.MirVer.GetLen()); // save the last known MirVer value even if the new one is empty
	return 0;
}
Beispiel #27
0
int ContactStatusChanged(MCONTACT hContact, WORD oldStatus, WORD newStatus)
{
	if (opt.LogToDB && (!opt.LogToDB_WinOpen || CheckMsgWnd(hContact))) {
		wchar_t stzStatusText[MAX_SECONDLINE] = { 0 };
		GetStatusText(hContact, newStatus, oldStatus, stzStatusText);
		T2Utf blob(stzStatusText);

		DBEVENTINFO dbei = {};
		dbei.cbBlob = (DWORD)mir_strlen(blob) + 1;
		dbei.pBlob = (PBYTE)blob;
		dbei.eventType = EVENTTYPE_STATUSCHANGE;
		dbei.flags = DBEF_READ | DBEF_UTF;

		dbei.timestamp = (DWORD)time(0);
		dbei.szModule = MODULE;
		MEVENT hDBEvent = db_event_add(hContact, &dbei);

		if (opt.LogToDB_WinOpen && opt.LogToDB_Remove) {
			DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT));
			dbevent->hContact = hContact;
			dbevent->hDBEvent = hDBEvent;
			eventListStatus.insert(dbevent);
		}
	}

	bool bEnablePopup = true, bEnableSound = true;
	char *szProto = GetContactProto(hContact);
	int myStatus = Proto_GetStatus(szProto);

	if (!mir_strcmp(szProto, META_PROTO)) { //this contact is Meta
		MCONTACT hSubContact = db_mc_getMostOnline(hContact);
		char *szSubProto = GetContactProto(hSubContact);
		if (szSubProto == nullptr)
			return 0;

		if (newStatus == ID_STATUS_OFFLINE) {
			// read last online proto for metacontact if exists,
			// to avoid notifying when meta went offline but default contact's proto still online
			DBVARIANT dbv;
			if (!db_get_s(hContact, szProto, "LastOnline", &dbv)) {
				szSubProto = NEWSTR_ALLOCA(dbv.pszVal);
				db_free(&dbv);
			}
		}
		else
			db_set_s(hContact, szProto, "LastOnline", szSubProto);

		if (db_get_b(0, MODULE, szSubProto, 1) == 0)
			return 0;

		szProto = szSubProto;
	}
	else {
		if (myStatus == ID_STATUS_OFFLINE || db_get_b(0, MODULE, szProto, 1) == 0)
			return 0;
	}

	if (!opt.FromOffline || oldStatus != ID_STATUS_OFFLINE) { // Either it wasn't a change from Offline or we didn't enable that.
		char buff[8];
		mir_snprintf(buff, "%d", newStatus);
		if (db_get_b(0, MODULE, buff, 1) == 0)
			return 0; // "Notify when a contact changes to one of..." is unchecked
	}

	if (SkipHiddenContact(hContact))
		return 0;

	// check if that proto from which we received statuschange notification, isn't in autodisable list
	if (opt.AutoDisable) {
		char statusIDs[12], statusIDp[12];
		mir_snprintf(statusIDs, "s%d", myStatus);
		mir_snprintf(statusIDp, "p%d", myStatus);
		bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : TRUE;
		bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : TRUE;
	}

	if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) {
		int wStatus = Proto_GetStatus(szProto);
		wchar_t str[MAX_SECONDLINE] = { 0 };
		if (opt.ShowStatus)
			GetStatusText(hContact, newStatus, oldStatus, str);

		if (opt.ReadAwayMsg && wStatus != ID_STATUS_INVISIBLE && StatusHasAwayMessage(szProto, newStatus))
			db_set_ws(hContact, MODULE, "LastPopupText", str);

		PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA));
		pdp->oldStatus = oldStatus;
		pdp->newStatus = newStatus;
		pdp->hAwayMsgHook = nullptr;
		pdp->hAwayMsgProcess = nullptr;
		ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, newStatus), newStatus, str, pdp);
	}

	if (opt.BlinkIcon && !opt.TempDisabled) {
		HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, newStatus) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE);
		wchar_t str[256];
		mir_snwprintf(str, TranslateT("%s is now %s"), Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText);
		BlinkIcon(hContact, hIcon, str);
	}

	if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) {
		if (oldStatus == ID_STATUS_OFFLINE)
			PlayChangeSound(hContact, StatusListEx[ID_STATUS_FROMOFFLINE].lpzSkinSoundName);
		else
			PlayChangeSound(hContact, StatusList[Index(newStatus)].lpzSkinSoundName);
	}

	if (opt.LogToFile) {
		wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN];

		GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime));
		GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate));
		mir_snwprintf(stzText, TranslateT("%s, %s. %s changed status to %s (was %s)\r\n"),
			stzDate, stzTime, Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText,
			StatusList[Index(oldStatus)].lpzStandardText);
		LogToFile(stzText);
	}

	return 0;
}
Beispiel #28
0
static INT_PTR CALLBACK LangOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	HWND hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST);
	LVITEM lvi;

	switch(msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		hwndLangOpt = hwndDlg;
		ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_LABELTIP);
		ListView_SetImageList(hwndList, CreateRadioImages(ListView_GetBkColor(hwndList), ListView_GetTextColor(hwndList)), LVSIL_STATE); /* auto-destroyed */
		{	
			LVCOLUMN lvc;
			lvc.mask = LVCF_TEXT;
			lvc.pszText = TranslateT("Installed Languages");
			ListView_InsertColumn(hwndList, 0, &lvc);
		}
		if ( ServiceExists(MS_FLAGS_LOADFLAGICON))
			ListView_SetImageList(hwndList, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR24, 8, 8), LVSIL_SMALL); 
		
		TCHAR szPath[MAX_PATH];
		GetPackPath(szPath, SIZEOF(szPath), FALSE, _T(""));
		SetDlgItemText(hwndDlg, IDC_SKINROOTFOLDER, szPath);

		SendMessage(hwndDlg, M_RELOADLIST, 0, 0);
		SendMessage(hwndDlg, M_SHOWFILECOL, 0, 1);
		return TRUE;

	case M_RELOADLIST:
		/* init list */
		ListView_DeleteAllItems(hwndList);
		ListView_DeleteColumn(hwndList, 1); /* if present */
		{
			HIMAGELIST himl = ListView_GetImageList(hwndList, LVSIL_SMALL);
			ImageList_RemoveAll(himl);
			/* enum all packs */
			EnumPacks(InsertPackItemEnumProc, _T("langpack_*.txt"), "Miranda Language Pack Version 1", (WPARAM)hwndList, (LPARAM)himl);
			/* make it use current langpack locale for sort */
			ListView_SortItems(hwndList, CompareListItem, CallService(MS_LANGPACK_GETLOCALE, 0, 0));
			//CheckDlgButton(hwndDlg, IDC_ENABLEAUTOUPDATES, db_get_b(NULL, "LangMan", "EnableAutoUpdates", SETTING_ENABLEAUTOUPDATES_DEFAULT) != 0);
			/* show selection */
			int iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
			if (iItem != -1)
				ListView_EnsureVisible(hwndList, iItem, FALSE);
		}
		return TRUE;

	case M_SHOWFILECOL:
		if ((BOOL)lParam && ListView_GetItemCount(hwndList) > 1) {
			/* add column */
			LVCOLUMN lvc;
			ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER);
			lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
			lvc.pszText = TranslateT("File");
			lvc.cx = 160;
			ListView_InsertColumn(hwndList, lvc.iSubItem = 1, &lvc);
			ListView_SetColumnWidth(hwndList, 0, ListView_GetColumnWidth(hwndList, 0) - lvc.cx);

			/* add text */
			lvi.mask = LVIF_PARAM;
			lvi.iSubItem = 0;
			for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
				LANGPACK_INFO *pack = (LANGPACK_INFO*)lvi.lParam;
				ListView_SetItemText(hwndList, lvi.iItem, 1, (pack->flags&LPF_DEFAULT) ? TranslateT("built-in") : pack->szFileName);
			}
		}
		else {
			ListView_DeleteColumn(hwndList, 1);
			ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER);
		}
		return TRUE;

	case WM_DESTROY:
		ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_LANGLIST));
		return TRUE;

	case WM_THEMECHANGED:
	case WM_SETTINGCHANGE:
		{
			HIMAGELIST himl = ListView_SetImageList(hwndList, CreateRadioImages(ListView_GetBkColor(hwndList), ListView_GetTextColor(hwndList)), LVSIL_STATE); /* auto-destroyed */
			if (himl != NULL)
				ImageList_Destroy(himl);
		}
		break;

	case WM_CTLCOLORLISTBOX: /* mimic readonly edit */
		return (BOOL)SendMessage(hwndDlg, WM_CTLCOLORSTATIC, wParam, lParam);

	case WM_COMMAND:
		switch(LOWORD(wParam)) {
		case IDC_LANGEMAIL:
			{
				char buf[512];
				lstrcpyA(buf, "mailto:");
				if (GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), &buf[7], sizeof(buf)-7))
					CallService(MS_UTILS_OPENURL, FALSE, (LPARAM)buf);
				return TRUE;
			}

		case IDC_MORELANG:
			CallService(MS_UTILS_OPENURL, TRUE, (LPARAM)"http://miranda-ng.org/");
			return TRUE;
		}
		break;

	case WM_CONTEXTMENU:
		if (GetDlgCtrlID((HWND)wParam) == IDC_LANGLIST) {
			/* get item */
			LVHITTESTINFO hti;
			POINTSTOPOINT(hti.pt, MAKEPOINTS(lParam));
			if (hti.pt.x == -1 && hti.pt.y == -1) {
				/* keyboard invoked */
				hti.iItem = ListView_GetNextItem((HWND)wParam, -1, LVNI_SELECTED);
				if (hti.iItem != -1)
					break;

				RECT rc;
				if (!ListView_GetItemRect((HWND)wParam, hti.iItem, &rc, LVIR_SELECTBOUNDS))
					break;

				hti.pt.x = rc.left + (rc.right - rc.left) / 2;
				hti.pt.y = rc.top + (rc.bottom - rc.top) / 2;
				ClientToScreen((HWND)wParam, &hti.pt);
			}
			else {
				ScreenToClient((HWND)wParam, &hti.pt);
				if (ListView_HitTest((HWND)wParam, &hti) == -1 || !(hti.flags&LVHT_ONITEM))
					break;
				POINTSTOPOINT(hti.pt, MAKEPOINTS(lParam));
			}

			/* param */
			lvi.iItem = hti.iItem;
			lvi.iSubItem = 0;
			lvi.mask = LVIF_PARAM;
			if (!ListView_GetItem((HWND)wParam, &lvi))
				break;

			/* context menu */
			LANGPACK_INFO *pack = (LANGPACK_INFO*)lvi.lParam;
			if (!(pack->flags & LPF_DEFAULT)) {
				HMENU hContextMenu = CreatePopupMenu();
				if (hContextMenu != NULL) {
					AppendMenu(hContextMenu, MF_STRING, 2, TranslateT("&Remove..."));
					if (TrackPopupMenuEx(hContextMenu, TPM_RETURNCMD | TPM_NONOTIFY | TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_HORPOSANIMATION | TPM_VERPOSANIMATION, hti.pt.x, hti.pt.y, (HWND)wParam, NULL))
						DeletePackFile(hwndDlg, (HWND)wParam, hti.iItem, pack);
					DestroyMenu(hContextMenu);
				}
			}
			return TRUE;
		}
		break;

	case WM_NOTIFYFORMAT:
		SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, NFR_UNICODE);
		return TRUE;

	case WM_NOTIFY:
		NMHDR *nmhdr = (NMHDR*)lParam;
		switch (nmhdr->idFrom) {
		case IDC_LANGLIST:
			switch (nmhdr->code) {
			case LVN_DELETEITEM:
				lvi.iItem = ((NMLISTVIEW*)lParam)->iItem; /* nmlv->lParam is invalid */
				lvi.iSubItem = 0;
				lvi.mask = LVIF_PARAM;
				if (ListView_GetItem(nmhdr->hwndFrom, &lvi))
					mir_free((LANGPACK_INFO*)lvi.lParam);
				break;

			case LVN_ITEMCHANGED:
				{
					NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
					if (!(nmlv->uChanged&LVIF_STATE))
						break;

					/* display info and check radio item */
					if (nmlv->uNewState&LVIS_SELECTED && !(nmlv->uOldState&LVIS_SELECTED)) {
						ListView_SetItemState(nmhdr->hwndFrom, nmlv->iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK);
						DisplayPackInfo(hwndDlg, (LANGPACK_INFO*)nmlv->lParam);
					}
					/* disable all other radio items */
					else if (nmlv->uNewState&INDEXTOSTATEIMAGEMASK(2)) {
						for (int iItem = ListView_GetItemCount(nmhdr->hwndFrom) - 1; iItem != -1; --iItem)
							if (iItem != nmlv->iItem)
								ListView_SetItemState(nmhdr->hwndFrom, iItem, INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK);

						/* enable apply */
						if (nmlv->uOldState) {
							SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
							ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), SW_SHOW);
						}
					}
				}
				break;

			case LVN_KEYDOWN:
				{
					int iItem = ListView_GetNextItem(nmhdr->hwndFrom, -1, LVNI_SELECTED);
					switch (((NMLVKEYDOWN*)lParam)->wVKey) {
					case VK_SPACE:
						ListView_SetItemState(nmhdr->hwndFrom, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK);
						break;

					case VK_DELETE:
						lvi.iItem = iItem;
						lvi.iSubItem = 0;
						lvi.mask = LVIF_PARAM;
						if (ListView_GetItem(nmhdr->hwndFrom, &lvi)) {
							LANGPACK_INFO *pack = (LANGPACK_INFO*)lvi.lParam;
							if (!(pack->flags&LPF_DEFAULT))
								DeletePackFile(hwndDlg, nmhdr->hwndFrom, iItem, pack);
						}
						break;
					}
				}
				break;

			case NM_CLICK:
				LVHITTESTINFO hti;
				lParam = GetMessagePos();
				POINTSTOPOINT(hti.pt, MAKEPOINTS(lParam));
				ScreenToClient(nmhdr->hwndFrom, &hti.pt);
				if (ListView_HitTest(nmhdr->hwndFrom, &hti) != -1)
					if (hti.flags&(LVHT_ONITEMSTATEICON | LVHT_ONITEMICON)) /* one of them */
						ListView_SetItemState(nmhdr->hwndFrom, hti.iItem, LVIS_SELECTED, LVIS_SELECTED);
			}
			break;

		case 0:
			switch (nmhdr->code) {
			case PSN_APPLY:
				lvi.mask = LVIF_STATE | LVIF_PARAM;
				lvi.stateMask = LVIS_STATEIMAGEMASK;
				lvi.iSubItem = 0;
				for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) {
					LANGPACK_INFO *pack = (LANGPACK_INFO*)lvi.lParam;
					if (lvi.state&INDEXTOSTATEIMAGEMASK(2) && !(pack->flags & LPF_ENABLED)) {
						if(!(pack->flags & LPF_DEFAULT))
							db_set_ws(NULL, "LangMan", "Langpack", pack->szFileName);
						else
							db_unset(NULL, "LangMan", "Langpack");
						TCHAR szPath[MAX_PATH];
						GetPackPath(szPath, SIZEOF(szPath), FALSE, pack->szFileName);
						CallService(MS_LANGPACK_RELOAD, 0, (LPARAM)szPath);
						pack->flags |= LPF_ENABLED;
						CloseWindow(GetParent(hwndDlg));
						DestroyWindow(GetParent(hwndDlg));
					}
					else pack->flags &= ~LPF_ENABLED;
				}
				return TRUE;
			}
		}
		break;
	}
	return FALSE;
}