summaryrefslogtreecommitdiff
path: root/icqj_mod/isee.c
diff options
context:
space:
mode:
Diffstat (limited to 'icqj_mod/isee.c')
-rw-r--r--icqj_mod/isee.c1324
1 files changed, 1324 insertions, 0 deletions
diff --git a/icqj_mod/isee.c b/icqj_mod/isee.c
new file mode 100644
index 0000000..697caec
--- /dev/null
+++ b/icqj_mod/isee.c
@@ -0,0 +1,1324 @@
+// ---------------------------------------------------------------------------80
+// ICQ plugin for Miranda Instant Messenger
+// ________________________________________
+//
+// Copyright © 2003,2004,2005 Bio
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+
+#include "icqoscar.h"
+//#include "../../plugins/mwclist/CLUIFrames/m_cluiframes.h"
+#include "resource.h"
+#include "isee.h"
+
+#include <m_skin.h>
+
+// Extern
+extern HANDLE hUserMenuStatus;
+extern void setUserInfo();
+
+//Popup
+#define ME_ICQ_POPUP "/IcqPopUp"
+static HANDLE hHookIcqPopUp = NULL;
+static HANDLE hPopUpFix = NULL;
+static BOOL bPopUpService = 0;
+static void PopUpMsg(HANDLE hContact, BYTE bType);
+
+
+// Status
+#define LISTSIZE 20
+
+static CRITICAL_SECTION slistmutex;
+static HANDLE hQueueEventS = NULL;
+static HANDLE hDummyEventS = NULL;
+static HANDLE hStatusMenu = NULL;
+
+static int LastContactID = 0;
+static int LastHidContactID = 0;
+static int LastFavContactID = 0;
+static int LastVIPContactID = 0;
+
+static int hVIPTimer = 0;
+static int hFavTimer = 0;
+static int hHidTimer = 0;
+static BYTE FLCStatus = 0;
+static WORD nPointer = 0;
+static WORD nCount = 0;
+static WORD defSpeed;
+static WORD nSpeed;
+
+typedef struct s_checkstatus {
+ DWORD dwUin;
+ DWORD dwCookie;
+} checkstatus;
+
+
+static checkstatus StatusList[LISTSIZE];
+static HANDLE hPrivacy[8] = {0}; // Def, 1, 2, 3, 4, 5, 6, Old
+
+static void RebuildMenu();
+
+
+// webaware
+static HANDLE hWebAware = NULL;
+static int icq_WebAware(WPARAM wParam,LPARAM lParam);
+
+// privacy tools
+static HANDLE hTools = NULL;
+static HANDLE hVisTools = NULL;
+
+BOOL PopUpErrMsg(char* aMsg)
+{
+ if (bPopUpService &&
+ !(DBGetContactSettingByte(NULL, gpszICQProtoName, "PopUpsMode", 0)) && !Miranda_Terminated()) {
+
+ NotifyEventHooks(hPopUpFix, (WPARAM)aMsg, 6);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+// status checking stuff
+void icq_CheckSpeed(WORD wStatus)
+{
+// 2 - slower! 3 - very slower! 4 - speed up!
+
+ switch (wStatus)
+ {
+ case 2: if (FLCStatus > 1) nSpeed = nSpeed + 1000; break;
+ case 3: if (FLCStatus > 1) nSpeed = nSpeed + 5000; break;
+ case 4: nSpeed = defSpeed; break;
+ default: break;
+ }
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Rate status recieved: %u. Delay: %u ms", wStatus, nSpeed);
+#endif
+
+}
+
+
+void icq_GetUserStatus(HANDLE hContact, WORD wEvent)
+{ /* Events:
+ 0 - from full list check
+ 1 - manually from menu
+ 2 - user went offline
+ 3 - add to list
+ 4 - found users check
+ 5 - favorite users check
+ 6 - VIP users check
+*/
+// ToDo: Check for events & options
+// ToDo: Check for duplicate uins ?!
+
+ DWORD dwUin = 0;
+
+ if (hContact && hContact != INVALID_HANDLE_VALUE)
+ dwUin = ICQGetContactSettingDword(hContact, UNIQUEIDSETTING, 0);
+
+ if (!ASD || !dwUin) return;
+
+ if ((wEvent == 2) &&
+ (DBGetContactSettingByte(hContact, "CList", "Hidden", 0) /*||
+ DBGetContactSettingByte(hContact, "CList", "NotOnList",0)*/))
+ return;
+
+ if ((wEvent == 3) &&
+ ICQGetContactSettingWord(hContact, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
+ return;
+
+ if (nCount < LISTSIZE)
+ {
+ int i,c;
+
+ EnterCriticalSection(&slistmutex);
+
+ c = nPointer + nCount;
+ if (c > LISTSIZE - 1) c = c - LISTSIZE;
+
+ if (nCount)
+ {
+
+ int y = 0;
+
+ if (c > nPointer) y = nPointer;
+
+ if (c>0) for (i=c-1; i>=y; i--)
+ if (StatusList[i].dwUin == dwUin)
+ {
+ LeaveCriticalSection(&slistmutex);
+ return;
+ }
+
+ if (y==0) for (i=LISTSIZE-1; i>=nPointer; i--)
+ if (StatusList[i].dwUin == dwUin)
+ {
+ LeaveCriticalSection(&slistmutex);
+ return;
+ }
+ }
+
+ nCount++;
+
+ StatusList[c].dwUin = dwUin;
+ StatusList[c].dwCookie = 0x100;
+
+ LeaveCriticalSection(&slistmutex);
+
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Queue user %u status, place %u, count %u, delay %u ms", dwUin, c, nCount, nSpeed);
+#endif
+ if (hQueueEventS) SetEvent(hQueueEventS);
+ }
+}
+
+
+static void icq_GetNextUserStatus()
+{
+
+ if (!nCount && (FLCStatus > 1))
+ {
+ HANDLE hContact;
+
+ if (FLCStatus == 3) // start from beginning
+ {
+ LastContactID = 0;
+ FLCStatus = 2;
+ }
+ else
+ if (LastContactID >= CacheIDCount()) // finish reached. stop scanning
+ {
+ char szSndName[MAX_PATH+30];
+
+ strcpy(szSndName, gpszICQProtoName);
+ strcat(szSndName, "/ScanComplete");
+
+ SkinPlaySound(szSndName);
+
+ LastContactID = 0;
+
+ FLCStatus = 0;
+ RebuildMenu();
+ PopUpMsg(NULL, 5);
+
+ return;
+ }
+
+ while (GetFromCacheByID(LastContactID++, &hContact, NULL))
+ {
+ if (ICQGetContactSettingWord(hContact, "Scan", 0x100) &&
+ !DBGetContactSettingByte(hContact, "CList", "Hidden", 0) &&
+ !DBGetContactSettingByte(hContact, "CList", "NotOnList", 0) &&
+ (ICQGetContactSettingWord(hContact, "Status", 0) == ID_STATUS_OFFLINE ||
+ CheckContactCapabilities(hContact, WAS_FOUND)))
+ {
+ icq_GetUserStatus(hContact, 0);
+ break;
+ }
+ }
+ }
+}
+
+
+void icq_SetUserStatus(DWORD dwUin, DWORD dwCookie, signed nStatus)
+{/* Statuses:
+
+ + online/invisible
+ - offline
+
+* active *
+
+ -1: Recieve server Ack
+ -4: Recipient is not logged in
+ 2: Received away message
+ 4: Incorrect SNAC format
+ 5: got caps
+
+* passive *
+
+
+ 21: type 1 msg
+ 22: type 2 msg
+ 24: type 4 msg
+ 25: MTN
+ 26: AUTH REQ
+ 27: // Added
+ 28: Auth Accept or Deny
+ 29: Removed from list
+
+*/
+
+// ToDo: Check for events & options
+
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Set status cmd: %d, Cookie: 0x%X, Uin: %d", nStatus, dwCookie, dwUin);
+#endif
+ if (!gbSetStatus) return;
+
+ if (!dwUin && ASD)
+ {
+
+ int i;
+ dwUin = 0;
+
+ EnterCriticalSection(&slistmutex);
+/*
+ for (i=0; i < LISTSIZE; i++) {
+ iters++;
+ if (StatusList[i].dwCookie == wCookie) {
+ dwUin = StatusList[i].dwUin;
+ StatusList[i].dwUin = 0;
+ StatusList[i].dwCookie = 0x100;
+ break;
+ }
+ }
+*/
+ if (nPointer>0)
+ for (i=nPointer-1; i>=0; i--)
+ if (StatusList[i].dwCookie == dwCookie)
+ {
+ dwUin = StatusList[i].dwUin;
+ StatusList[i].dwUin = 0;
+ StatusList[i].dwCookie = 0x100;
+ break;
+ }
+
+ if (!dwUin)
+ for (i=LISTSIZE-1; i>=nPointer; i--)
+ if (StatusList[i].dwCookie == dwCookie)
+ {
+ dwUin = StatusList[i].dwUin;
+ StatusList[i].dwUin = 0;
+ StatusList[i].dwCookie = 0x100;
+ break;
+ }
+
+ LeaveCriticalSection(&slistmutex);
+ }
+
+ if (!dwUin) return;
+
+ hContact = HContactFromUIN(dwUin, 0);
+
+ if (hContact && hContact != INVALID_HANDLE_VALUE)
+ {
+ char name[128];
+
+ NickFromHandleStatic(hContact, name, sizeof(name));
+
+ if ((nStatus < 0) && ASD) { // user is not here 8-(
+
+ Netlib_Logf(ghServerNetlibUser, "%s (%d) is not here 8-(", name, dwUin);
+
+ makeUserOffline(hContact);
+
+ } else { // user is here 8-)
+
+ if (nStatus <= 5) Netlib_Logf(ghServerNetlibUser, "%s (%d) is here 8-)", name, dwUin);
+
+ if (ICQGetContactSettingWord(hContact, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ {
+
+ time_t TimeStamp = time(NULL);
+
+ if ((nStatus <= 5) &&
+ !DBGetContactSettingByte(hContact, "CList", "Hidden", 0) &&
+ !DBGetContactSettingByte(hContact, "CList", "NotOnList", 0) &&
+ !(DBGetContactSettingDword(hContact, "Ignore","Mask1", 0) & 0x8))
+ PopUpMsg(hContact, 4);
+
+ if (nStatus != 5)
+ {
+ ICQWriteContactSettingWord(hContact, "Status", ID_STATUS_INVISIBLE);
+ ICQWriteContactSettingDword(hContact, "OldLogonTS", (DWORD)TimeStamp);
+ ClearAllContactCapabilities(hContact);
+ }
+
+ SetContactCapabilities(hContact, WAS_FOUND);
+ ClearContactCapabilities(hContact, CAPF_SRV_RELAY); // for compability
+
+ // dim icon
+ if (!ICQGetContactSettingDword(hContact, "IdleTS", 0))
+ ICQWriteContactSettingDword(hContact, "IdleTS", (DWORD)TimeStamp);
+
+ }
+ }
+
+ if (hDummyEventS) SetEvent(hDummyEventS);
+ }
+
+}
+
+
+void __cdecl icq_StatusCheckThread(void* arg)
+{
+
+ DWORD dwWait;
+ BOOL bKeepRunning = TRUE;
+ BOOL sent;
+
+ while (bKeepRunning)
+ {
+
+ // Wait for a while
+ ResetEvent(hQueueEventS);
+
+ if (nCount > 0) {
+ dwWait = WaitForSingleObjectEx(hDummyEventS, nSpeed*2, TRUE); //max delay
+ if (Miranda_Terminated()) bKeepRunning = FALSE;
+ } else
+ {
+ dwWait = WaitForSingleObjectEx(hQueueEventS, 2000, TRUE);
+ while (dwWait == WAIT_TIMEOUT)
+ {
+
+ if (Miranda_Terminated()) bKeepRunning = FALSE;
+ if (!bKeepRunning) break;
+
+ dwWait = WaitForSingleObjectEx(hQueueEventS, 10000, TRUE);
+ }
+ }
+
+ ResetEvent(hDummyEventS);
+
+ switch (dwWait) {
+
+ case WAIT_IO_COMPLETION:
+ // Possible shutdown in progress
+ if (Miranda_Terminated())
+ bKeepRunning = FALSE;
+ break;
+
+ case WAIT_OBJECT_0:
+ case WAIT_TIMEOUT:
+ // Time to check for users status
+ if (icqOnline) {
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Users statuses %u", nCount);
+#endif
+ if (nCount > 0)
+ {
+ //icq_packet p;
+ int iRes = FALSE;
+ HANDLE hContact = NULL;
+
+ sent = 1;
+
+ EnterCriticalSection(&slistmutex);
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Request user %u status", StatusList[nPointer].dwUin);
+#endif
+ // getting invisibility via status message
+ hContact = HContactFromUIN(StatusList[nPointer].dwUin, 0);
+ if (gbDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD))
+ {
+ iRes = icq_sendGetAwayMsgDirect(hContact, MTYPE_AUTOAWAY);
+ }
+ if(!iRes)
+ icq_sendGetAwayMsgServ(StatusList[nPointer].dwUin, MTYPE_AUTOAWAY, (WORD)(ICQGetContactSettingWord(hContact, "Version", 0)==9?9:ICQ_VERSION)); // Success
+
+ StatusList[nPointer].dwCookie = GenerateCookie(0);
+
+ // use common and well documented thing. it now works!
+ // seems AOL always leave something or fix in one place add bug to another :)
+ // icq_GetCaps(StatusList[nPointer].dwUin, (WORD)(StatusList[nPointer].dwCookie));
+
+ nCount--;
+ if (nPointer == LISTSIZE - 1) nPointer = 0;
+ else nPointer++;
+
+ LeaveCriticalSection(&slistmutex);
+
+ if (nSpeed > defSpeed) nSpeed = nSpeed - 250;
+ }
+
+ if (FLCStatus > 1)
+ {
+ icq_GetNextUserStatus();
+ SleepEx(1500, TRUE);
+ }
+
+ if (sent)
+ {
+ SleepEx(nSpeed, TRUE);
+ sent = 0;
+ }
+
+ }
+ break;
+
+ default:
+ // Something strange happened. Exit
+ bKeepRunning = FALSE;
+ break;
+ }
+ }
+
+ ExitProcess(-1);
+ return;
+
+}
+
+
+static void CALLBACK TimeToCheckHidden(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime)
+{
+
+ if (icqOnline && nCount < 3)
+ {
+ HANDLE hContact;
+
+ if (LastHidContactID >= CacheIDCount())
+ {
+ LastHidContactID = 0;
+ }
+
+ while (GetFromCacheByID(LastHidContactID++, &hContact, NULL))
+ {
+ // check found users but skip VIPs & hidden from contact list
+ DWORD Scan = ICQGetContactSettingByte(hContact, "Scan", 0x100);
+
+ if (CheckContactCapabilities(hContact, WAS_FOUND) &&
+// (DBGetContactSettingWord(hContact, gpszICQProtoName, "Status", 0) == ID_STATUS_INVISIBLE) &&
+ Scan != 2 &&
+ !DBGetContactSettingByte(hContact, "CList", "Hidden", 0))
+// !DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)
+ {
+ icq_GetUserStatus(hContact, 4);
+ if (ICQGetContactSettingWord(hContact, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ ClearAllContactCapabilities(hContact);
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Checking found user... (%u)", DBGetContactSettingDword(hContact,gpszICQProtoName, UNIQUEIDSETTING,0));
+#endif
+ break;
+ }
+
+ }
+
+ }
+
+}
+
+
+static void CALLBACK TimeToCheckFav(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime)
+{
+
+ if (icqOnline && nCount < 3)
+ {
+
+ HANDLE hContact;
+
+ if (LastFavContactID >= CacheIDCount())
+ {
+ LastFavContactID = 0;
+ }
+
+ while (GetFromCacheByID(LastFavContactID++, &hContact, NULL))
+ {
+ // check favorite users
+ if ((ICQGetContactSettingByte(hContact, "Scan", 0x100) == 1)
+ && ICQGetContactSettingWord(hContact, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ {
+ icq_GetUserStatus(hContact, 5);
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Checking Favorite user... (%u)", DBGetContactSettingDword(hContact,gpszICQProtoName, UNIQUEIDSETTING,0));
+#endif
+ break;
+ }
+
+ }
+
+ }
+
+}
+
+
+static void CALLBACK TimeToCheckVIP(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime)
+{
+
+ if (icqOnline && nCount < 3)
+ {
+ HANDLE hContact;
+
+ if (LastVIPContactID >= CacheIDCount())
+ {
+ LastVIPContactID = 0;
+ }
+
+ while (GetFromCacheByID(LastVIPContactID++, &hContact, NULL))
+ {
+ // check favorite users
+ if ((ICQGetContactSettingByte(hContact, "Scan", 0x100) == 2) &&
+ (ICQGetContactSettingWord(hContact, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE
+ || CheckContactCapabilities(hContact, WAS_FOUND)))
+ {
+ icq_GetUserStatus(hContact, 6);
+#ifdef _DEBUG
+ Netlib_Logf(ghServerNetlibUser, "Checking VIP user... (%u)", DBGetContactSettingDword(hContact,gpszICQProtoName, UNIQUEIDSETTING,0));
+#endif
+ break;
+ }
+
+ }
+
+ }
+
+}
+
+
+// menu stuff
+static int icq_CheckUserStatus(WPARAM wParam,LPARAM lParam)
+{
+ if (icqOnline)
+ icq_GetUserStatus((HANDLE)wParam, 1);
+ return 0;
+}
+
+
+int icq_CheckAllUsersStatus(WPARAM wParam,LPARAM lParam)
+{
+
+ BYTE OldStatus = FLCStatus;
+
+ if (icqOnline)
+ {
+ switch (OldStatus) {
+ case 0:
+ case 1: FLCStatus = 2; break;
+ default: FLCStatus = 1; break;
+ }
+
+ }
+ else
+ {
+ switch (OldStatus) {
+ case 0: FLCStatus = 3; break;
+ case 1: FLCStatus = 0; break;
+ default: FLCStatus = 1; break;
+ }
+ }
+
+ if (FLCStatus > 1)
+ icq_GetNextUserStatus();
+
+ RebuildMenu();
+
+ return 0;
+}
+
+
+static void RebuildMenu()
+{
+
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+
+ switch (FLCStatus) {
+ case 0:// stopped
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_STOP));
+ break;
+
+ case 1: // paused
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_PAUSE));
+ break;
+
+ default: // working
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_START));
+ break;
+ }
+
+ mi.flags = CMIM_ICON;// | CMIM_NAME;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hStatusMenu, (LPARAM)&mi);
+
+}
+int IcqSetInvis(WPARAM wparam,LPARAM lparam)
+{
+ CallContactService((HANDLE)wparam,PSS_SETAPPARENTMODE,(DBGetContactSettingWord((HANDLE)wparam,(const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wparam,0),"ApparentMode",0)==ID_STATUS_OFFLINE)?0:ID_STATUS_OFFLINE,0);
+ return 0;
+}
+
+
+// set visible-flag in db
+int IcqSetVis(WPARAM wparam,LPARAM lparam)
+{
+ CallContactService((HANDLE)wparam,PSS_SETAPPARENTMODE,(DBGetContactSettingWord((HANDLE)wparam,(const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wparam,0),"ApparentMode",0)==ID_STATUS_ONLINE)?0:ID_STATUS_ONLINE,0);
+ return 0;
+}
+
+static void SetPrivacy(BYTE newVisibility)
+{
+ CLISTMENUITEM mi = {0};
+
+ if (!gbSsiEnabled || gbVisibility == newVisibility) return;
+
+ gbVisibility = newVisibility;
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON;
+
+ if (hPrivacy[7])
+ {
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_DOT));
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hPrivacy[7], (LPARAM)&mi);
+ }
+
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_CHECK));
+ hPrivacy[7] = hPrivacy[gbVisibility];
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hPrivacy[7], (LPARAM)&mi);
+
+ if (icqOnline)
+ {
+ if (gbVisibility)
+ updateServVisibilityCode(gbVisibility);
+ else
+ updateServVisibilityCode(gnCurrentStatus == ID_STATUS_INVISIBLE ? DEFAULT_INVISIBLEMODE : gbVisibleMode);
+ }
+
+
+ DBWriteContactSettingByte(NULL, gpszICQProtoName, "Privacy", gbVisibility);
+
+}
+
+
+static int icq_Privacy0(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(0);
+ return 0;
+}
+
+static int icq_Privacy1(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(1);
+ return 0;
+}
+
+static int icq_Privacy2(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(2);
+ return 0;
+}
+
+static int icq_Privacy3(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(3);
+ return 0;
+}
+
+static int icq_Privacy4(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(4);
+ return 0;
+}
+
+static int icq_Privacy5(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(5);
+ return 0;
+}
+
+static int icq_Privacy6(WPARAM wParam,LPARAM lParam)
+{
+ SetPrivacy(6);
+ return 0;
+}
+
+static int icq_SList(WPARAM wParam, LPARAM lParam)
+{
+ if (gbSsiEnabled)
+ ShowUploadContactsDialog();
+
+ return 0;
+}
+
+
+// self remove
+static void icq_sendRemoveMe(DWORD dwUin)
+{
+ icq_packet p;
+ unsigned char szUin[10], nUinlen;
+
+ if (!dwUin) return;
+
+ ltoa(dwUin, szUin, 10);
+ nUinlen = strlen(szUin);
+
+ p.wLen = 11 + nUinlen;
+ write_flap(&p, ICQ_DATA_CHAN);
+ packFNACHeader(&p, ICQ_LISTS_FAMILY, ICQ_LISTS_REVOKEAUTH, 0, ICQ_LISTS_REVOKEAUTH); //0x03
+ packByte(&p, nUinlen);
+ packBuffer(&p, szUin, nUinlen);
+
+ sendServPacket(&p);
+}
+
+
+static BOOL CALLBACK ConfirmRemoveProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)GetWindowLong(hwndDlg, GWL_USERDATA);
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ if (!lParam)
+ EndDialog(hwndDlg, 0);
+
+ SetWindowLong(hwndDlg, GWL_USERDATA, lParam);
+ hContact = (HANDLE)lParam;
+ TranslateDialogDefault(hwndDlg);
+ {
+ char title[256];
+ char name[128];
+ DWORD dwUin;
+ //HICON hIcon=LoadIcon(NULL, IDI_WARNING);
+ HICON hIcon=LoadIcon(hIconInst, MAKEINTRESOURCE(IDI_REMOVE));
+ SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)hIcon);
+ DestroyIcon(hIcon);
+
+ NickFromHandleStatic(hContact, name, sizeof(name));
+ dwUin = DBGetContactSettingDword(hContact, gpszICQProtoName, UNIQUEIDSETTING, 0);
+ mir_snprintf(title, sizeof(title), "%s (%u) - %s", name, dwUin, Translate("Remove confirmation"));
+ SetWindowTextA(hwndDlg, title);
+
+ SetDlgItemTextA(hwndDlg,IDC_CONFIRMATION,Translate("Are you sure you want to remove yourself from this user's contact list ?"));
+
+ }
+ return TRUE;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ if (!icqOnline) return TRUE;
+ icq_sendRemoveMe(DBGetContactSettingDword(hContact, gpszICQProtoName, UNIQUEIDSETTING, 0));
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+ }
+ break;
+ case IDCANCEL:
+ EndDialog(hwndDlg, 0);
+ return TRUE;
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+ case WM_CLOSE:
+ EndDialog(hwndDlg,0);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+int icq_SelfRemove(WPARAM wParam, LPARAM lParam)
+{
+ if (wParam && icqOnline)
+ DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CONFIRM), NULL, ConfirmRemoveProc, (LPARAM)wParam);
+
+ return 0;
+}
+
+
+int icq_Tools(WPARAM wParam, LPARAM lParam)
+{
+ CLISTMENUITEM mi = {0};
+
+ gbTools = !gbTools;
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON;
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(gbTools?IDI_CHECK:IDI_DOT));
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hTools, (LPARAM)&mi);
+
+ DBWriteContactSettingByte(NULL, gpszICQProtoName, "PrivacyItems", gbTools);
+
+ return 0;
+}
+
+int icq_Vis_Tools(WPARAM wParam, LPARAM lParam)
+{
+ CLISTMENUITEM mi = {0};
+
+ gbVTools = !gbVTools;
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON;
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(gbVTools?IDI_CHECK:IDI_DOT));
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hVisTools, (LPARAM)&mi);
+
+ DBWriteContactSettingByte(NULL, gpszICQProtoName, "VisibilityItems", gbVTools);
+
+ return 0;
+}
+
+//
+static void icq_sendGrantAuth(DWORD dwUin)
+{
+ icq_packet p;
+ unsigned char szUin[10], nUinlen;
+
+ if (!dwUin) return;
+
+ ltoa(dwUin, szUin, 10);
+ nUinlen = strlen(szUin);
+
+ serverPacketInit(&p, 15 + nUinlen);
+ packFNACHeader(&p, ICQ_LISTS_FAMILY, ICQ_LISTS_GRANTAUTH);
+ packByte(&p, nUinlen);
+ packBuffer(&p, szUin, nUinlen);
+ packDWord(&p, 0);
+
+ sendServPacket(&p);
+}
+
+
+int icq_GrantAuth(WPARAM wParam,LPARAM lParam)
+{
+ if (icqOnline && wParam)
+ icq_sendGrantAuth(ICQGetContactSettingDword((HANDLE)wParam, UNIQUEIDSETTING, 0));
+
+ return 0;
+}
+
+
+// popups stuff
+static void PopUpMsg(HANDLE hContact, BYTE bType)
+{
+ switch(bType) {
+ case 4: // User was found
+ ShowPopUpMsg(hContact, NickFromHandleUtf(hContact), ICQTranslateUtf ("...was found!"), LOG_FOUND);
+ break;
+ case 5: // Scan complete
+ ShowPopUpMsg(hContact, ICQTranslateUtf ("Active Status Scan"), ICQTranslateUtf ("Users Status Scan Complete"), LOG_FINISHED);
+ break;
+ default:
+ return;
+ }
+}
+
+void icq_ISeeCleanup()
+{
+ if (ASD)
+ {
+ if (hHidTimer) KillTimer(NULL, hHidTimer);
+ if (hFavTimer) KillTimer(NULL, hFavTimer);
+ if (hVIPTimer) KillTimer(NULL, hVIPTimer);
+ DeleteCriticalSection(&slistmutex);
+ CloseHandle(hQueueEventS);
+ CloseHandle(hDummyEventS);
+ }
+}
+
+void icq_InitISee()
+{
+
+ int i;
+ char pszName[MAX_PATH+30], pszServiceName[MAX_PATH+30];
+
+ CLISTMENUITEM mi={0};
+ mi.cbSize = sizeof(mi);
+
+ // some globals
+ gbSetStatus = 1;
+ gbTools = DBGetContactSettingByte(NULL, gpszICQProtoName, "PrivacyItems", DEFAULT_TOOLS);
+ gbVTools = DBGetContactSettingByte(NULL, gpszICQProtoName, "VisibilityItems", DEFAULT_VISIBILITY_TOOLS);
+ gbVisibility = DEFAULT_VISIBILITY;
+ gbWebAware = DBGetContactSettingByte(NULL, gpszICQProtoName, "WebAware", 0);
+ gdwUpdateThreshold = DBGetContactSettingByte(NULL, gpszICQProtoName, "InfoUpdate", UPDATE_THRESHOLD/(3600*24))*3600*24;
+
+#ifdef _DEBUG
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_TEST2");
+ CreateServiceFunction(pszServiceName, icq_Test2);
+
+ mi.position = 1000010000;
+// mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(ID_SCAN));
+ mi.pszContactOwner = gpszICQProtoName;
+ mi.pszName = Translate("TEST");
+ mi.pszService = pszServiceName;
+ CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+#endif
+
+ ASD = 0;
+
+ switch (ICQGetContactSettingByte(NULL, "ASD", 2)) {
+
+ case 2: ICQWriteContactSettingByte(NULL, "ASD", (ASD?1:0));
+ if (!ASD) break;
+ case 1:
+ hQueueEventS = CreateEvent(NULL, FALSE, FALSE, NULL);
+ hDummyEventS = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ {
+ char szName[MAX_PATH+30];
+ char szSndName[MAX_PATH+30];
+
+ strcpy(szSndName, gpszICQProtoName);
+ strcat(szSndName, "/ScanComplete");
+
+ _snprintf(szName, sizeof(szName), "%s: %s", gpszICQProtoName, Translate("Status Scan Complete"));
+
+ SkinAddNewSound(szSndName, szName, "scancomplete.wav");
+ }
+
+ defSpeed = ICQGetContactSettingWord(NULL, "_defSpeed", 6000);
+ nSpeed = defSpeed;
+
+ if (hQueueEventS && hDummyEventS) {
+
+ InitializeCriticalSection(&slistmutex);
+
+ // Init list
+ for (i = 0; i<LISTSIZE; i++) {
+ StatusList[i].dwUin = 0;
+ StatusList[i].dwCookie = 0x100;
+ }
+ forkthread(icq_StatusCheckThread, 0, 0);
+ }
+
+ if (TRUE) hHidTimer = SetTimer(NULL, 1, 600000, TimeToCheckHidden);
+ if (TRUE) hFavTimer = SetTimer(NULL, 1, 450000, TimeToCheckFav);
+ if (TRUE) hVIPTimer = SetTimer(NULL, 1, 300000, TimeToCheckVIP);
+
+ ASD = 1;
+ break;
+ case 0:
+ ASD = 0;
+ break;
+ }
+
+ if (ASD)
+ {
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_CUS");
+ CreateServiceFunction(pszServiceName, icq_CheckUserStatus);
+
+ mi.position = 1000055000;
+ mi.flags = 0;
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_SCAN));
+ mi.pszContactOwner = gpszICQProtoName;
+ mi.pszName = Translate("Us&er Status");
+ mi.pszService = pszServiceName;
+ hUserMenuStatus = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) & mi);
+
+ mir_snprintf(pszName, sizeof(pszName), "%s (%s)", Translate("&Users Status Scan"), Translate(gpszICQProtoName));
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_CAUS");
+ CreateServiceFunction(pszServiceName, icq_CheckAllUsersStatus);
+
+ mi.position = 400060000;
+ mi.pszName = pszName;
+ mi.pszService = pszServiceName;
+ hStatusMenu = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+ RebuildMenu();
+ }
+
+ if (DBGetContactSettingByte(NULL, gpszICQProtoName, "PrivacyMenu", DEFAULT_PRIVACY_ENABLED))
+ {
+ gbVisibility = DBGetContactSettingByte(NULL, gpszICQProtoName, "Privacy", DEFAULT_VISIBILITY);
+ if (gbVisibility > 6) gbVisibility = DEFAULT_VISIBILITY;
+
+ mir_snprintf(pszName, sizeof(pszName), "%s (%s)", Translate("Privacy Settings"), Translate(gpszICQProtoName));
+
+ mi.pszPopupName = pszName;
+ mi.flags = 0;
+ mi.popupPosition=400059000;
+ // icon for menu
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_PRIVACY));
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR0");
+ CreateServiceFunction(pszServiceName, icq_Privacy0);
+
+ mi.position = 2000000000;
+ mi.pszName = Translate("Default, corresponding to status");
+ mi.pszService = pszServiceName;
+ hPrivacy[0] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR1");
+ CreateServiceFunction(pszServiceName, icq_Privacy1);
+
+ // icon for other items
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_DOT));
+
+ mi.position = 2000010000;
+ mi.pszName = Translate("Allow all users to see you");
+ mi.pszService = pszServiceName;
+ hPrivacy[1] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR2");
+ CreateServiceFunction(pszServiceName, icq_Privacy2);
+
+ mi.position = 2000020000;
+ mi.pszName = Translate("Block all users from seeing you");
+ mi.pszService = pszServiceName;
+ hPrivacy[2] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR3");
+ CreateServiceFunction(pszServiceName, icq_Privacy3);
+
+ mi.position = 2000030000;
+ mi.pszName = Translate("Allow only users in the Visible list to see you");
+ mi.pszService = pszServiceName;
+ hPrivacy[3] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR4");
+ CreateServiceFunction(pszServiceName, icq_Privacy4);
+
+ mi.position = 2000040000;
+ mi.pszName = Translate("Block only users in the Invisible list from seeing you");
+ mi.pszService = pszServiceName;
+ hPrivacy[4] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR5");
+ CreateServiceFunction(pszServiceName, icq_Privacy5);
+
+ mi.position = 2000050000;
+ mi.pszName = Translate("Allow only users in the Contact list to see you");
+ mi.pszService = pszServiceName;
+ hPrivacy[5] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_PR6");
+ CreateServiceFunction(pszServiceName, icq_Privacy6);
+
+ mi.position = 2000060000;
+ mi.pszName = Translate("As previous except Invisible list users");
+ mi.pszService = pszServiceName;
+ hPrivacy[6] = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ // set checkmark
+ mi.flags = CMIM_ICON;
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_CHECK));
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hPrivacy[gbVisibility], (LPARAM)&mi);
+
+ hPrivacy[7] = hPrivacy[gbVisibility];
+
+ // fix first menu item icon
+ if (gbVisibility != 0)
+ {
+ // mi.flags = CMIM_ICON;
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(IDI_DOT));
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hPrivacy[0], (LPARAM)&mi);
+
+ }
+
+ mi.flags = 0;
+
+ // webaware
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(gbWebAware?IDI_CHECK:IDI_DOT));
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_WA");
+ CreateServiceFunction(pszServiceName, icq_WebAware);
+
+ mi.position = 2100000000;
+ mi.pszName = Translate("WebAware");
+ mi.pszService = pszServiceName;
+ hWebAware = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ // Remove option
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(gbTools?IDI_CHECK:IDI_DOT));
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_ISEE_TOOLS");
+ CreateServiceFunction(pszServiceName, icq_Tools);
+
+ mi.position = 2105000000;
+ mi.pszName = Translate("Show privacy tools in user's menu"); //("Enable 'Remove from user's list' option");
+ mi.pszService = pszServiceName;
+ hTools = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ //Vis Tools
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(gbVTools?IDI_CHECK:IDI_DOT));
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_VIS_TOOLS");
+ CreateServiceFunction(pszServiceName, icq_Vis_Tools);
+
+ mi.position = 2106000000;
+ mi.pszName = Translate("Show visibility tools in user's menu"); //("Enable 'Remove from user's list' option");
+ mi.pszService = pszServiceName;
+ hVisTools = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ // Manage server list
+ mi.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_LIST));//
+
+ strcpy(pszServiceName, gpszICQProtoName); strcat(pszServiceName, "PS_SERVER_LIST");
+ CreateServiceFunction(pszServiceName, icq_SList);
+
+ mi.position = 2107000000;
+ mi.pszName = Translate("Manage server's list...");
+ mi.pszService = pszServiceName;
+ CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) & mi);
+
+ }
+
+ // Added by BM
+ SkinAddNewSoundEx("AuthRequest", Translate("ISee"), Translate("Authorization Request"));
+ SkinAddNewSoundEx("AuthDenied", Translate("ISee"), Translate("Authorization Denied"));
+ SkinAddNewSoundEx("AuthGranted", Translate("ISee"), Translate("Authorization Granted"));
+ SkinAddNewSoundEx("YouWereAdded", Translate("ISee"), Translate("You Were Added"));
+ SkinAddNewSoundEx("ContactRemovedSelf", Translate("ISee"), Translate("Contact Removed Self"));
+}
+
+
+
+void SetWebAware(BYTE bSend)
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON;
+ mi.hIcon = LoadIcon(hIconInst,MAKEINTRESOURCE(gbWebAware?IDI_CHECK:IDI_DOT));
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hWebAware, (LPARAM)&mi);
+
+ if (icqOnline && bSend)
+ {
+ PBYTE buf = NULL;
+ int buflen = 2;
+
+ ppackTLVByte(&buf, &buflen, (BYTE)gbWebAware, TLV_WEBAWARE, 1);
+
+ *(PWORD)buf = buflen - 2;
+
+ IcqChangeInfoEx(META_SET_FULLINFO_REQ, (LPARAM)buf);
+
+ SAFE_FREE(buf);
+
+ icq_setstatus(MirandaStatusToIcq(gnCurrentStatus));
+ }
+}
+
+
+static int icq_WebAware(WPARAM wParam,LPARAM lParam)
+{
+ gbWebAware = !gbWebAware;
+
+ DBWriteContactSettingByte(NULL, gpszICQProtoName, "WebAware", gbWebAware);
+
+ SetWebAware(1);
+
+ return 0;
+}
+// 0 - delete
+// 1 - add
+void sendVisContactServ(DWORD dwUin, int mode)
+{
+
+ int ID;
+ BYTE len;
+ char szUin[20];
+ icq_packet packet;
+ icq_contacts_cache icc;
+ WORD type = (mode)?CLI_ADDTEMPVISIBLE:CLI_REMOVETEMPVISIBLE;
+
+ if (!icqOnline || !gbSsiEnabled || gbVisibility != 6) return;
+
+ ID = IDFromCacheByUin(dwUin);
+ GetCacheByID(ID, &icc);
+
+ if (mode && !(icc.flags & F_TEMPVIS))
+ {
+ // mark contact
+ SetCacheFlagsByID(ID, icc.flags|F_TEMPVIS);
+ }
+ else
+ if (!mode && (icc.flags & F_TEMPVIS))
+ {
+ SetCacheFlagsByID(ID, icc.flags &~ F_TEMPVIS);
+ }
+ else
+ return;
+
+ _itoa(dwUin, szUin, 10);
+ len = strlen(szUin);
+
+ packet.wLen = len + 11;
+ write_flap(&packet, 2);
+ packFNACHeader(&packet, ICQ_BOS_FAMILY, type, 0, 0);
+ packByte(&packet, len);
+ packBuffer(&packet, szUin, len);
+ sendServPacket(&packet);
+
+}
+
+
+// 0 - delete
+// 1 - add
+void sendVisListServ(int mode)
+{
+ char *szList;
+ char szUin[20];
+ char szLen[2];
+ WORD wListLen = 0;
+ int ID = 0;
+ icq_packet packet;
+ icq_contacts_cache icc;
+ WORD type = (mode)?CLI_ADDTEMPVISIBLE:CLI_REMOVETEMPVISIBLE;
+
+ int count = CacheIDCount();
+
+ if (!count) return;
+
+ szList = (char*)alloca((count + 1) * 11);
+ szList[0] = 0;
+ szLen[1] = 0;
+
+ while(GetCacheByID(ID++, &icc))
+ {
+
+ if (icc.dwUin == dwLocalUIN)
+ continue;
+
+ if (mode) // for adding
+ {
+ if (DBGetContactSettingByte(icc.hContact, "CList", "NotOnList", 0) ||
+ (icc.flags & F_TEMPVIS)) // skip already added
+ continue;
+
+ // mark contact
+ SetCacheFlagsByID(ID - 1, icc.flags|F_TEMPVIS);
+ }
+ else
+ if (icc.flags & F_TEMPVIS)
+ {
+ // unmark contact
+ SetCacheFlagsByID(ID - 1, icc.flags &~ F_TEMPVIS);
+ }
+ else
+ continue;
+
+ _itoa(icc.dwUin, szUin, 10);
+ szLen[0] = strlen(szUin);
+
+ strcat(szList, szLen);
+ strcat(szList, szUin);
+
+ wListLen += szLen[0] + 1;
+
+ if (wListLen > MAX_MESSAGESNACSIZE)
+ break;
+ }
+
+ if (wListLen)
+ {
+ packet.wLen = wListLen + 10;
+ write_flap(&packet, 2);
+ packFNACHeader(&packet, ICQ_BOS_FAMILY, type, 0, 0);
+ packBuffer(&packet, szList, wListLen);
+ sendServPacket(&packet);
+ }
+
+} \ No newline at end of file