From 8e2a004d967dd3faea172fbed655b0b45c826d54 Mon Sep 17 00:00:00 2001 From: Tobias Weimer Date: Fri, 9 Jan 2015 19:38:12 +0000 Subject: SkypeClassic: Upmerge with leecher's repo: -Implemented Filetransfer extensions for receiving files and avatars via SkypeProxy (sending via SkypeProxy not working yet). -Added option to disable the check for SENT messages as newer Skype versions don't send this notification anymore. -Various little code fixes. Other changes: - Fixed memory leak - Fixed crash in x64 builds - Translation fixes git-svn-id: http://svn.miranda-ng.org/main/trunk@11805 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeClassic/SkypeClassic_10.vcxproj | 3 + .../SkypeClassic/SkypeClassic_10.vcxproj.filters | 9 + protocols/SkypeClassic/res/Resource.rc | 250 +++++-------- protocols/SkypeClassic/src/contacts.cpp | 32 +- protocols/SkypeClassic/src/filexfer.cpp | 400 +++++++++++++++++++++ protocols/SkypeClassic/src/filexfer.h | 9 + protocols/SkypeClassic/src/gchat.cpp | 83 ++--- protocols/SkypeClassic/src/msglist.cpp | 16 +- protocols/SkypeClassic/src/msglist.h | 1 + protocols/SkypeClassic/src/resource.h | 7 +- protocols/SkypeClassic/src/skype.cpp | 193 +++++++--- protocols/SkypeClassic/src/skype.h | 35 +- protocols/SkypeClassic/src/skypeapi.cpp | 168 +++++++-- protocols/SkypeClassic/src/skypeapi.h | 8 +- protocols/SkypeClassic/src/skypeopt.cpp | 18 +- protocols/SkypeClassic/src/skypeproxy/skypeproxy.h | 35 +- .../SkypeClassic/src/skypeproxy/skypeproxy_int.h | 32 ++ protocols/SkypeClassic/src/skypesvc.cpp | 41 +-- protocols/SkypeClassic/src/version.h | 2 +- 19 files changed, 933 insertions(+), 409 deletions(-) create mode 100644 protocols/SkypeClassic/src/filexfer.cpp create mode 100644 protocols/SkypeClassic/src/filexfer.h create mode 100644 protocols/SkypeClassic/src/skypeproxy/skypeproxy_int.h (limited to 'protocols/SkypeClassic') diff --git a/protocols/SkypeClassic/SkypeClassic_10.vcxproj b/protocols/SkypeClassic/SkypeClassic_10.vcxproj index ab43a5a327..0c122f8a36 100644 --- a/protocols/SkypeClassic/SkypeClassic_10.vcxproj +++ b/protocols/SkypeClassic/SkypeClassic_10.vcxproj @@ -21,6 +21,7 @@ + @@ -49,6 +50,7 @@ + @@ -66,6 +68,7 @@ + diff --git a/protocols/SkypeClassic/SkypeClassic_10.vcxproj.filters b/protocols/SkypeClassic/SkypeClassic_10.vcxproj.filters index d505b70d11..c7ef6065d9 100644 --- a/protocols/SkypeClassic/SkypeClassic_10.vcxproj.filters +++ b/protocols/SkypeClassic/SkypeClassic_10.vcxproj.filters @@ -63,6 +63,9 @@ Source Files + + Source Files + @@ -119,6 +122,9 @@ Header Files + + Header Files + @@ -184,6 +190,9 @@ Resource Files\Icons + + Resource Files + diff --git a/protocols/SkypeClassic/res/Resource.rc b/protocols/SkypeClassic/res/Resource.rc index 7bfd83e121..7ea0257a07 100644 --- a/protocols/SkypeClassic/res/Resource.rc +++ b/protocols/SkypeClassic/res/Resource.rc @@ -1,4 +1,4 @@ -//Microsoft Developer Studio generated resource script. +// Microsoft Visual C++ generated resource script. // #include "..\src\resource.h" @@ -16,10 +16,8 @@ // Neutral resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1252) -#endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // @@ -27,57 +25,47 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // IDD_SETAVATAR DIALOGEX 0, 0, 222, 131 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN PUSHBUTTON "Set",IDC_SETAVATAR,10,108,45,13,WS_GROUP PUSHBUTTON "Delete",IDC_DELETEAVATAR,57,108,45,13 - CONTROL "",IDC_AVATAR,"Static",SS_BITMAP | SS_CENTERIMAGE | - SS_SUNKEN | WS_GROUP,10,10,96,93 + CONTROL "",IDC_AVATAR,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN | WS_GROUP,10,10,96,93 END IDD_OPT_DEFAULT DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "Start Skype with Miranda NG if not running using the following command line options:", - IDC_STARTSKYPE,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,10 - CONTROL "/NOSPLASH - Don't show splash screen on startup", - IDC_NOSPLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,17, - 264,12 + CONTROL "Start Skype with Miranda NG if not running using the following command line options:",IDC_STARTSKYPE, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,4,290,10 + CONTROL "/NOSPLASH - Don't show splash screen on startup",IDC_NOSPLASH, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,17,264,12 CONTROL "/MINIMIZED - Start Skype minimized",IDC_MINIMIZED, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,28,264,12 - CONTROL "/NOTRAY - Skype tray icon becomes gray and is therefore ""invisible""", - IDC_NOTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,40, - 264,12 - CONTROL "/REMOVEABLE - For running portable Skype", - IDC_REMOVEABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36, - 51,264,12 + CONTROL "/NOTRAY - Skype tray icon becomes gray and is therefore ""invisible""",IDC_NOTRAY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,40,264,12 + CONTROL "/REMOVEABLE - For running portable Skype",IDC_REMOVEABLE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,51,264,12 CONTROL "/SECONDARY - This is the second instance",IDC_SECONDARY, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,62,264,12 CONTROL "/DATAPATH - Specify Skype data folder*",IDC_DATAPATHO, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,74,264,12 EDITTEXT IDC_DATAPATH,47,88,236,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_BROWSEDP,285,87,16,15 - CONTROL "Use custom Skype executable*",IDC_CUSTOMCOMMAND,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,36,103,264,10 + CONTROL "Use custom Skype executable*",IDC_CUSTOMCOMMAND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,103,264,10 EDITTEXT IDC_COMMANDLINE,47,116,236,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_BROWSECMDL,285,115,16,15 - CTEXT "* Relative path root is Miranda NG folder", - IDC_STATIC_PATHINFO,10,136,290,8,NOT WS_GROUP + CTEXT "* Relative path root is Miranda NG folder",IDC_STATIC_PATHINFO,10,136,290,8,NOT WS_GROUP CONTROL "Shutdown Skype when you close Miranda NG",IDC_SHUTDOWN, - "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,151, - 290,10 - CONTROL "Unload Skype when you change to Offline status", - IDC_UNLOADOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,164,290,11 + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,151,290,10 + CONTROL "Unload Skype when you change to Offline status",IDC_UNLOADOFFLINE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,164,290,11 LTEXT "Try at least",IDC_STATIC,10,185,39,8 EDITTEXT IDC_CONNATTEMPTS,52,183,21,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "times to connect to Skype API before giving up", - IDC_STATIC,78,185,224,8,NOT WS_GROUP + LTEXT "times to connect to Skype API before giving up",IDC_STATIC,78,185,224,8,NOT WS_GROUP LTEXT "User name:",IDC_STATIC,10,206,38,8 EDITTEXT IDC_USERNAME,52,204,79,12,ES_AUTOHSCROLL LTEXT "Password:",IDC_STATIC,148,206,34,8 @@ -85,34 +73,29 @@ BEGIN END IDD_DIAL DIALOGEX 0, 0, 198, 46 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Dial" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN LTEXT "Number:",IDC_STATIC,7,8,30,11 - COMBOBOX IDC_NUMBER,41,6,149,13,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_NUMBER,41,6,149,13,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "Dial",IDDIAL,88,25,50,14,WS_GROUP PUSHBUTTON "Cancel",IDCANCEL,141,25,50,14 END IDD_CALLSTAT DIALOGEX 0, 0, 220, 67 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION CAPTION "%s is calling" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "Join conference with %s",IDC_JOIN,"Button", - BS_AUTORADIOBUTTON | WS_GROUP,7,7,206,10 - CONTROL "Answer call; set call to %s on hold",IDC_HOLD,"Button", - BS_AUTORADIOBUTTON,7,19,206,10 - CONTROL "Hang up",IDC_HANGUP,"Button",BS_AUTORADIOBUTTON,7,31, - 206,10 + CONTROL "Join conference with %s",IDC_JOIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP,7,7,206,10 + CONTROL "Answer call; set call to %s on hold",IDC_HOLD,"Button",BS_AUTORADIOBUTTON,7,19,206,10 + CONTROL "Hang up",IDC_HANGUP,"Button",BS_AUTORADIOBUTTON,7,31,206,10 DEFPUSHBUTTON "OK",IDOK,163,46,50,14,WS_GROUP END IDD_INPUTBOX DIALOGEX 0, 0, 221, 46 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN @@ -122,7 +105,7 @@ BEGIN END IDD_OPTIONS DIALOGEX 0, 0, 313, 249 -STYLE DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN @@ -130,39 +113,33 @@ BEGIN END IDD_OPT_PROXY DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "Use Skype proxy connection over network instead of local Skype API", - IDC_USES2S,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,9 + CONTROL "Use Skype proxy connection over network instead of local Skype API",IDC_USES2S, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,4,290,9 LTEXT "Host:",IDC_STATIC_HOST,20,21,18,10 EDITTEXT IDC_HOST,41,19,133,12,ES_AUTOHSCROLL LTEXT "Port:",IDC_STATIC_PORT,180,21,16,10,0,WS_EX_RIGHT EDITTEXT IDC_PORT,200,19,29,12,ES_AUTOHSCROLL | ES_NUMBER - CTEXT "* You must restart Miranda NG in order to let the settings take effect", - IDC_STATIC_RESTART,10,54,290,8,NOT WS_GROUP - CONTROL "This Skype proxy requires password authentication:", - IDC_REQPASS,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,20,38,176,9 + CTEXT "* You must restart Miranda NG in order to let the settings take effect",IDC_STATIC_RESTART,10,54,290,8,NOT WS_GROUP + CONTROL "This Skype proxy requires password authentication:",IDC_REQPASS, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,20,38,176,9 EDITTEXT IDC_PASSWORD,200,36,82,12,ES_PASSWORD | ES_AUTOHSCROLL END IDD_SETDETAILS DIALOGEX 0, 0, 216, 151 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN LTEXT "Name:",IDC_STATIC,7,6,61,9 EDITTEXT IDC_FULLNAME,73,4,141,12,ES_AUTOHSCROLL LTEXT "Birthday:",IDC_STATIC,7,20,61,9 - CONTROL "DateTimePicker1",IDC_BIRTHDAY,"SysDateTimePick32", - DTS_RIGHTALIGN | DTS_APPCANPARSE | WS_TABSTOP,73,18,62, - 12 + CONTROL "DateTimePicker1",IDC_BIRTHDAY,"SysDateTimePick32",DTS_RIGHTALIGN | DTS_APPCANPARSE | WS_TABSTOP,73,18,62,12 LTEXT "Sex:",IDC_STATIC,7,34,61,9 - COMBOBOX IDC_SEX,73,32,141,12,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_SEX,73,32,141,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "City:",IDC_STATIC,7,48,61,9 EDITTEXT IDC_CITY,73,46,141,12,ES_AUTOHSCROLL LTEXT "Country:",IDC_STATIC,7,62,61,9 @@ -179,90 +156,64 @@ BEGIN END IDD_OPT_ADVANCED DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "Enable Skype menu options (currently: Find/Add user)", - IDC_ENABLEMENU,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,9 + CONTROL "Enable Skype menu options (currently: Find/Add user)",IDC_ENABLEMENU, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,4,290,9 CONTROL "Use popup plugin for displaying messages",IDC_USEPOPUP, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,290,9 - CONTROL "Suppress all error messages (not recommended, but if it annoys you... ;)", - IDC_NOERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,34, - 290,9 - CONTROL "Use group chat interface for conversations (requires group chat module)", - IDC_GROUPCHAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 49,290,9 - CONTROL "Mark group chat message as read to avoid notification", - IDC_GROUPCHATREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,64,290,9 - CONTROL "Keep requested online status on startup under every circumstance", - IDC_KEEPSTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 79,290,9 - CONTROL "Use time zone patch",IDC_TIMEZONE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,94,290,9 - CONTROL "Ignore time zones",IDC_IGNTZ,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,109,290,9 - CONTROL "Show default Skype avatar for contacts", - IDC_SHOWDEFAULTAVATAR,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,124,290,9 - CONTROL "Suppress call summary chat message", - IDC_SUPPRESSCALLSUMMARYMESSAGE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,139,290,9 - CONTROL "Disable support for N/A and SkypeMe status (for Skype 4+)", - IDC_NOSKYPE3STATS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,154,290,9 - CONTROL "Show full name in contact list instead of nickname", - IDC_SHOWFULLNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,169,290,9 - LTEXT "SkypeOut contacts are in status:",IDC_STATIC,10,186,108, - 8 - COMBOBOX IDC_SKYPEOUTSTAT,120,184,79,54,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Cleanup Nicknames",IDC_CLEANUP,9,201,80,14,BS_MULTILINE | - WS_GROUP + CONTROL "Suppress all error messages (not recommended, but if it annoys you... ;)",IDC_NOERRORS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,34,290,9 + CONTROL "Use group chat interface for conversations (requires group chat module)",IDC_GROUPCHAT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,49,290,9 + CONTROL "Mark group chat message as read to avoid notification",IDC_GROUPCHATREAD, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,64,290,9 + CONTROL "Keep requested online status on startup under every circumstance",IDC_KEEPSTATE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,79,290,9 + CONTROL "Use time zone patch",IDC_TIMEZONE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,94,290,9 + CONTROL "Ignore time zones",IDC_IGNTZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,109,290,9 + CONTROL "Show default Skype avatar for contacts",IDC_SHOWDEFAULTAVATAR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,124,290,9 + CONTROL "Suppress call summary chat message",IDC_SUPPRESSCALLSUMMARYMESSAGE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,139,290,9 + CONTROL "Disable support for N/A and SkypeMe status (for Skype 4+)",IDC_NOSKYPE3STATS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,154,290,9 + CONTROL "Show full name in contact list instead of nickname",IDC_SHOWFULLNAME, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,169,290,9 + LTEXT "SkypeOut contacts are in status:",IDC_STATIC,10,200,108,8 + COMBOBOX IDC_SKYPEOUTSTAT,119,198,79,54,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Cleanup Nicknames",IDC_CLEANUP,220,199,80,14,BS_MULTILINE | WS_GROUP + CONTROL "Do not wait for message SENT acknowledgement (for some buggy Skype versions >6)",IDC_NOACK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,182,290,13 END IDD_OPT_POPUP DIALOGEX 0, 0, 310, 228 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN GROUPBOX "Skype Popups",IDC_STATIC,0,1,309,227 GROUPBOX "Incoming Calls",IDC_STATIC,6,16,297,62,WS_GROUP - CONTROL "Show incoming calls",IDC_POPUPINCOMING,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,28,278,8 + CONTROL "Show incoming calls",IDC_POPUPINCOMING,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,28,278,8 EDITTEXT IDC_POPUPTIME,16,41,20,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "seconds",IDC_STATIC,41,43,92,8,NOT WS_GROUP - CONTROL "",IDC_POPUPBACKCOLOR,"ColourPicker",WS_GROUP | - WS_TABSTOP,142,40,39,12 - LTEXT "Background",IDC_STATIC_POPUPBACKCOLOR,186,42,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - CONTROL "Use Windows colors",IDC_USEWINCOLORS,"Button", - BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16,58, - 121,8 - CONTROL "",IDC_POPUPTEXTCOLOR,"ColourPicker",WS_TABSTOP,142,55, - 39,12 - LTEXT "Text",IDC_STATIC_POPUPTEXTCOLOR,186,56,50,8, - SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "",IDC_POPUPBACKCOLOR,"ColourPicker",WS_GROUP | WS_TABSTOP,142,40,39,12 + LTEXT "Background",IDC_STATIC_POPUPBACKCOLOR,186,42,50,8,SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "Use Windows colors",IDC_USEWINCOLORS,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16,58,121,8 + CONTROL "",IDC_POPUPTEXTCOLOR,"ColourPicker",WS_TABSTOP,142,55,39,12 + LTEXT "Text",IDC_STATIC_POPUPTEXTCOLOR,186,56,50,8,SS_CENTERIMAGE | NOT WS_GROUP PUSHBUTTON "Preview",IDC_PREVIEW,247,58,50,14,WS_GROUP GROUPBOX "Error Messages",IDC_STATIC,6,81,297,62,WS_GROUP - CONTROL "Display error messages",IDC_POPUPERROR,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,94,278,8 + CONTROL "Display error messages",IDC_POPUPERROR,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,94,278,8 EDITTEXT IDC_POPUPTIMEERR,16,107,20,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "seconds",IDC_STATIC,41,109,92,8,NOT WS_GROUP - CONTROL "",IDC_POPUPBACKCOLORERR,"ColourPicker",WS_GROUP | - WS_TABSTOP,142,106,39,12 - LTEXT "Background",IDC_STATIC_POPUPBACKCOLORERR,186,108,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - CONTROL "Use Windows colors",IDC_USEWINCOLORSERR,"Button", - BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16, - 124,121,8 - CONTROL "",IDC_POPUPTEXTCOLORERR,"ColourPicker",WS_TABSTOP,142, - 121,39,12 - LTEXT "Text",IDC_STATIC_POPUPTEXTCOLORERR,186,123,50,8, - SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "",IDC_POPUPBACKCOLORERR,"ColourPicker",WS_GROUP | WS_TABSTOP,142,106,39,12 + LTEXT "Background",IDC_STATIC_POPUPBACKCOLORERR,186,108,50,8,SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "Use Windows colors",IDC_USEWINCOLORSERR,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16,124,121,8 + CONTROL "",IDC_POPUPTEXTCOLORERR,"ColourPicker",WS_TABSTOP,142,121,39,12 + LTEXT "Text",IDC_STATIC_POPUPTEXTCOLORERR,186,123,50,8,SS_CENTERIMAGE | NOT WS_GROUP PUSHBUTTON "Preview",IDC_PREVIEWERR,247,124,50,14,WS_GROUP END @@ -273,7 +224,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE +GUIDELINES DESIGNINFO BEGIN IDD_SETAVATAR, DIALOG BEGIN @@ -356,47 +307,44 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_SKYPE ICON DISCARDABLE "skype.ico" -IDI_INVITE ICON DISCARDABLE "Invite.ico" -IDI_ADD ICON DISCARDABLE "add.ico" -IDI_IMPORT ICON DISCARDABLE "import.ico" -IDI_ERRORS ICON DISCARDABLE "error.ico" -IDI_MESSAGE ICON DISCARDABLE "message.ico" -IDI_CALL ICON DISCARDABLE "call.ico" -IDI_CALLSKYPEOUT ICON DISCARDABLE "skypeout.ico" -IDI_HOLD ICON DISCARDABLE "hold.ico" -IDI_RESUME ICON DISCARDABLE "resume.ico" -IDI_HANGUP ICON DISCARDABLE "hang_up.ico" -IDI_ONLINE ICON DISCARDABLE "online.ico" -IDI_CHAT ICON DISCARDABLE "chat.ico" -IDI_AWAY ICON DISCARDABLE "away.ico" -IDI_NA ICON DISCARDABLE "na.ico" -IDI_OCCUPIED ICON DISCARDABLE "occupied.ico" -IDI_DND ICON DISCARDABLE "dnd.ico" -IDI_INVISIBLE ICON DISCARDABLE "invisible.ico" -IDI_OFFLINE ICON DISCARDABLE "offline.ico" -IDI_PHONE ICON DISCARDABLE "phone.ico" -IDI_BLOCKCONTACT ICON DISCARDABLE "blockcon.ico" - +IDI_SKYPE ICON "skype.ico" +IDI_INVITE ICON "Invite.ico" +IDI_ADD ICON "add.ico" +IDI_IMPORT ICON "import.ico" +IDI_ERRORS ICON "error.ico" +IDI_MESSAGE ICON "message.ico" +IDI_CALL ICON "call.ico" +IDI_CALLSKYPEOUT ICON "skypeout.ico" +IDI_HOLD ICON "hold.ico" +IDI_RESUME ICON "resume.ico" +IDI_HANGUP ICON "hang_up.ico" +IDI_ONLINE ICON "online.ico" +IDI_CHAT ICON "chat.ico" +IDI_AWAY ICON "away.ico" +IDI_NA ICON "na.ico" +IDI_OCCUPIED ICON "occupied.ico" +IDI_DND ICON "dnd.ico" +IDI_INVISIBLE ICON "invisible.ico" +IDI_OFFLINE ICON "offline.ico" +IDI_PHONE ICON "phone.ico" +IDI_BLOCKCONTACT ICON "blockcon.ico" ///////////////////////////////////////////////////////////////////////////// // // Bitmap // -IDB_CALL BITMAP MOVEABLE PURE "res\\call.bmp" +IDB_CALL BITMAP "call.bmp" #endif // Neutral resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// Deutsch (Österreich) resources +// German (Austria) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA) -#ifdef _WIN32 LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN #pragma code_page(1252) -#endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -423,7 +371,7 @@ END #endif // APSTUDIO_INVOKED -#endif // Deutsch (Österreich) resources +#endif // German (Austria) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/protocols/SkypeClassic/src/contacts.cpp b/protocols/SkypeClassic/src/contacts.cpp index 1e94deb493..f07139775d 100644 --- a/protocols/SkypeClassic/src/contacts.cpp +++ b/protocols/SkypeClassic/src/contacts.cpp @@ -12,7 +12,7 @@ // Imported Globals extern HINSTANCE hInst; -extern BOOL bSkypeOut, bIsImoproxy; +extern BOOL bSkypeOut, bIsImoproxy, bHasFileXfer; extern char protocol, g_szProtoName[]; // Handles @@ -173,8 +173,10 @@ HANDLE add_contextmenu(MCONTACT) { // We cannot use flag PF1_FILESEND for sending files, as Skype opens its own // sendfile-Dialog. - mi = FileTransferItem(); - hMenuFileTransferItem = Menu_AddContactMenuItem(&mi); + if (!bHasFileXfer) { + mi = FileTransferItem(); + hMenuFileTransferItem = Menu_AddContactMenuItem(&mi); + } mi = ChatInitItem(); hMenuChatInitItem = Menu_AddContactMenuItem(&mi); @@ -255,11 +257,19 @@ int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM) { // File sending and groupchat-creation works starting with protocol version 5 if (protocol >= 5) { - mi = FileTransferItem(); - if (db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0) - mi.flags ^= CMIF_HIDDEN; - mi.flags |= CMIM_FLAGS; - Menu_ModifyItem(hMenuFileTransferItem, &mi); + if (!bHasFileXfer) { + mi = FileTransferItem(); + if (db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0) + mi.flags ^= CMIF_HIDDEN; + mi.flags |= CMIM_FLAGS; + Menu_ModifyItem(hMenuFileTransferItem, &mi); + } + mi = BlockContactItem(); + mi.flags ^= CMIF_HIDDEN; + mi.flags |= CMIM_FLAGS | CMIM_NAME; + if (db_get_b(hContact, SKYPE_PROTONAME, "IsBlocked", 0) == 1) + mi.ptszName = LPGENT("Unblock contact"); + Menu_ModifyItem(hMenuBlockContactItem, &mi); } if (protocol >= 5 || bIsImoproxy) { @@ -269,12 +279,6 @@ int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM) { mi.flags ^= CMIF_HIDDEN; mi.flags |= CMIM_FLAGS; Menu_ModifyItem(hMenuChatInitItem, &mi); - mi = BlockContactItem(); - mi.flags ^= CMIF_HIDDEN; - mi.flags |= CMIM_FLAGS | CMIM_NAME; - if (db_get_b(hContact, SKYPE_PROTONAME, "IsBlocked", 0) == 1) - mi.ptszName = LPGENT("Unblock contact"); - Menu_ModifyItem(hMenuBlockContactItem, &mi); } } diff --git a/protocols/SkypeClassic/src/filexfer.cpp b/protocols/SkypeClassic/src/filexfer.cpp new file mode 100644 index 0000000000..e27afa9f42 --- /dev/null +++ b/protocols/SkypeClassic/src/filexfer.cpp @@ -0,0 +1,400 @@ +#include "skype.h" +#include "skypeapi.h" +#include "utf8.h" +#include "msglist.h" +#include "pthread.h" + +extern char g_szProtoName[]; + +/* Services */ +INT_PTR SkypeRecvFile(WPARAM, LPARAM lParam) +{ + DBEVENTINFO dbei = { 0 }; + CCSDATA *ccs = (CCSDATA *)lParam; + PROTORECVEVENT *pre = (PROTORECVEVENT *)ccs->lParam; + size_t cbFilename, nFiles; + INT_PTR ret = 0; + + db_unset(ccs->hContact, "CList", "Hidden"); + dbei.cbSize = sizeof(dbei); + dbei.szModule = SKYPE_PROTONAME; + dbei.timestamp = pre->timestamp; + if (pre->flags & PREF_CREATEREAD) dbei.flags |= DBEF_READ; + if (pre->flags & PREF_UTF) dbei.flags |= DBEF_UTF; + dbei.eventType = EVENTTYPE_FILE; + dbei.cbBlob=sizeof(DWORD); + if (pre->flags & PREF_UNICODE) { + for(nFiles=0;cbFilename=wcslen((wchar_t*)&pre->szMessage[dbei.cbBlob])*sizeof(wchar_t);nFiles++) + dbei.cbBlob+=cbFilename+sizeof(wchar_t); + dbei.cbBlob+=sizeof(wchar_t); + } else { + for(nFiles=0;cbFilename=strlen(&pre->szMessage[dbei.cbBlob]);nFiles++) + dbei.cbBlob+=cbFilename+1; + dbei.cbBlob++; + } + dbei.pBlob = (PBYTE)pre->szMessage; + + TYP_MSGLENTRY *pEntry = MsgList_Add(pre->lParam, db_event_add(ccs->hContact, &dbei)); + if (pEntry) { + DWORD cbSize = sizeof(PROTOFILETRANSFERSTATUS); + /* Allocate basic entry and fill some stuff we already know */ + if (pEntry->pfts = calloc(1, cbSize)) { + PROTOFILETRANSFERSTATUS *pfts = (PROTOFILETRANSFERSTATUS*)pEntry->pfts; + size_t iOffs=sizeof(DWORD); + + pfts->cbSize = cbSize; + pfts->hContact = ccs->hContact; + pfts->totalFiles = nFiles; + if (pfts->pszFiles=(char**)calloc(nFiles+1, sizeof(char*))) { + if (pre->flags & PREF_UNICODE) { + wchar_t *pFN; + for (size_t i=0; cbFilename=wcslen(pFN=(wchar_t*)&pre->szMessage[iOffs])*sizeof(wchar_t); i++) { + pfts->pszFiles[i]=(char*)wcsdup(pFN); + iOffs+=cbFilename+sizeof(wchar_t); + } + } else { + char *pFN; + for(size_t i=0;cbFilename=strlen(pFN=&pre->szMessage[iOffs]);i++) { + pfts->pszFiles[i]=strdup(pFN); + iOffs+=cbFilename+1; + } + if (pre->flags & PREF_UTF) pfts->flags |= PFTS_UTF; + } + ret = pre->lParam; + } + } + } + return ret; +} + +INT_PTR SkypeSendFile(WPARAM, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA *)lParam; + DBVARIANT dbv; + char *mymsgcmd, *utfmsg = NULL, *pszFile=NULL; + TCHAR **files = (TCHAR**)ccs->lParam; + int nFiles, iLen = 0, ret=0; + BYTE bIsChatroom = 0 != db_get_b(ccs->hContact, SKYPE_PROTONAME, "ChatRoom", 0); + + if (bIsChatroom) { + if (db_get_s(ccs->hContact, SKYPE_PROTONAME, "ChatRoomID", &dbv)) + return 0; + mymsgcmd = "CHATFILE"; + } else { + if (db_get_s(ccs->hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return 0; + mymsgcmd = "FILE"; + } + for (nFiles=0; files[nFiles]; nFiles++) { + utfmsg=(char*)make_utf8_string(files[nFiles]); + iLen+=strlen(utfmsg)+3; + if (pszFile=pszFile?(char*)realloc(pszFile, iLen):(char*)calloc(1,iLen)) { + if (nFiles>0) strcat(pszFile, ","); + strcat(pszFile, "\""); + strcat(pszFile, utfmsg); + strcat(pszFile, "\""); + } + free(utfmsg); + } + if (pszFile) { + if (SkypeSend("%s %s %s", mymsgcmd, dbv.pszVal, pszFile) == 0) { + /* No chatmessage IDs available for filetransfers, there is no possibility + * in SkypeKit to check if incoming filetransfer SENT message belongs to + * the last file sent :( */ + char *str = SkypeRcvTime("CHATFILE", SkypeTime(NULL), INFINITE); + if (str) { + if (strncmp(str, "ERROR", 5)) { + char *pTok=strtok(str+9, " "); + + if (pTok) { + ret=strtoul(pTok, NULL, 10); + TYP_MSGLENTRY *pEntry = MsgList_Add(ret, INVALID_HANDLE_VALUE); + if (pEntry) { + DWORD cbSize = sizeof(PROTOFILETRANSFERSTATUS); + /* Allocate basic entry and fill some stuff we already know */ + if (pEntry->pfts = calloc(1, cbSize)) { + PROTOFILETRANSFERSTATUS *pfts = (PROTOFILETRANSFERSTATUS*)pEntry->pfts; + + pfts->cbSize = cbSize; + pfts->hContact = ccs->hContact; + pfts->totalFiles = nFiles; + pfts->flags = PFTS_SENDING; + if (pfts->pszFiles=(char**)calloc(nFiles+1, sizeof(char*))) { + for (int i=0; ipszFiles)[i]=_tcsdup(files[i]); + } + } + + } + } + } + free(str); + } + } + free(pszFile); + } + db_free(&dbv); + return ret; +} + +INT_PTR SkypeFileAllow(WPARAM, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA *)lParam; + if (!ccs || !ccs->lParam || !ccs->wParam) + return 0; + + TYP_MSGLENTRY *pEntry = MsgList_FindMessage(ccs->wParam); + if(!pEntry) + return 0; + + char *pszMsgNum, szMsgNum[16]; + sprintf(szMsgNum, "%d", ccs->wParam); + char *pszXferIDs = SkypeGetErr("CHATMESSAGE", szMsgNum, "FILETRANSFERS"); + if (!pszXferIDs) + return 0; + + INT_PTR ret = 0; + char *pszDir = (char*)make_utf8_string((wchar_t*)ccs->lParam); + if (pszDir) { + for (pszMsgNum = strtok(pszXferIDs, ", "); pszMsgNum; pszMsgNum = strtok(NULL, ", ")) { + if (SkypeSend("ALTER FILETRANSFER %s ACCEPT %s", pszMsgNum, pszDir)!=-1) { + char *ptr = SkypeRcv("ALTER FILETRANSFER ACCEPT", 2000); + if (ptr) { + if (strncmp(ptr, "ERROR", 5)) + ret = ccs->wParam; + free(ptr); + } + } + } + + /* Now we know the save directory in pfts */ + PROTOFILETRANSFERSTATUS *pfts = (PROTOFILETRANSFERSTATUS*)pEntry->pfts; + pfts->szWorkingDir = pszDir; + } + free(pszXferIDs); + return ret; +} + +INT_PTR SkypeFileCancel(WPARAM, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA *)lParam; + if (!ccs || !ccs->wParam) + return 0; + + char *pszMsgNum, szMsgNum[16], *ptr; + sprintf(szMsgNum, "%d", ccs->wParam); + char *pszXferIDs = SkypeGetErr("CHATMESSAGE", szMsgNum, "FILETRANSFERS"); + if (!pszXferIDs) + return 0; + INT_PTR ret = 1; + for (pszMsgNum = strtok(pszXferIDs, ", "); pszMsgNum; pszMsgNum = strtok(NULL, ", ")) { + if (SkypeSend ("ALTER FILETRANSFER %s CANCEL", pszMsgNum)!=-1) { + if (ptr=SkypeRcv("ALTER FILETRANSFER CANCEL", 2000)) { + if (strncmp(ptr, "ERROR", 5)) + ret=0; + free(ptr); + } + } + } + free(pszXferIDs); + return ret; +} + +void FXFreePFTS(void *Ppfts) +{ + PROTOFILETRANSFERSTATUS *pfts = (PROTOFILETRANSFERSTATUS*)Ppfts; + + if (pfts->pszFiles) + { + for (int i=0; itotalFiles; i++) + free(pfts->pszFiles[i]); + free(pfts->pszFiles); + free(pfts->szWorkingDir); + } + free(pfts); +} + +BOOL FXHandleRecv(PROTORECVEVENT *pre, MCONTACT hContact) +{ + // Our custom Skypekit FILETRANSFER extension + size_t cbMsg = sizeof(DWORD), cbNewSize; + + char szMsgNum[16]; + sprintf (szMsgNum, "%d", pre->lParam); + char *pszXferIDs = SkypeGetErr("CHATMESSAGE", szMsgNum, "FILETRANSFERS"); + if (!pszXferIDs) + return FALSE; + for (char *pszMsgNum = strtok(pszXferIDs, ", "); pszMsgNum; pszMsgNum = strtok(NULL, ", ")) + { + char *pszStatus = SkypeGetErrID("FILETRANSFER", pszMsgNum, "STATUS"); + if (pszStatus) + { + if (!strcmp(pszStatus, "NEW") || !strcmp(pszStatus, "PLACEHOLDER")) + { + char *pszType = SkypeGetErr("FILETRANSFER", pszMsgNum, "TYPE"); + if (pszType) + { + if (!strcmp(pszType, "INCOMING")) + { + char *pszFN = SkypeGetErr("FILETRANSFER", pszMsgNum, "FILENAME"); + if (pszFN) + { + cbNewSize = cbMsg+strlen(pszFN)+2; + if ((pre->szMessage = (char*)realloc(pre->szMessage, cbNewSize))) + { + memcpy(pre->szMessage+cbMsg, pszFN, cbNewSize-cbMsg-1); + cbMsg=cbNewSize-1; + } else pszMsgNum=NULL; + pre->flags |= PREF_UTF; + free(pszFN); + } + } + free (pszType); + } + } + free(pszStatus); + } + } + free(pszXferIDs); + if (pre->szMessage) + { + CCSDATA ccs = {0}; + + *((TCHAR*)&pre->szMessage[cbMsg])=0; + *((DWORD*)pre->szMessage)=pre->lParam; + ccs.szProtoService = PSR_FILE; + ccs.hContact = hContact; + ccs.wParam = 0; + ccs.lParam = (LPARAM)pre; + CallServiceSync(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); + free(pre->szMessage); + return TRUE; + } + return FALSE; +} + +typedef struct { + BOOL bStatus; + char szNum[16]; + char szArg[32]; +} ft_args; + +void FXHandleMessageThread(ft_args *pargs) +{ + char *pszChat = SkypeGetErr("FILETRANSFER", pargs->szNum, "CHATMESSAGE"); + if (!pszChat) { + free(pargs); + return; + } + + DWORD dwChat = strtoul(pszChat, NULL, 10); + TYP_MSGLENTRY *pEntry = MsgList_FindMessage(dwChat); + if(!pEntry) { + free(pargs); + free(pszChat); + return; + } + + MCONTACT hContact = ((PROTOFILETRANSFERSTATUS*)pEntry->pfts)->hContact; + if(!hContact) { + free(pargs); + free(pszChat); + return; + } + + if (pargs->bStatus) { + if (!strcmp(pargs->szArg, "CONNECTING")) + ProtoBroadcastAck(SKYPE_PROTONAME, hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)dwChat, 0); + else if (!strncmp(pargs->szArg, "TRANSFERRING", 12)) + ProtoBroadcastAck(SKYPE_PROTONAME, hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)dwChat, 0); + else if (!strcmp(pargs->szArg, "FAILED")) + ProtoBroadcastAck(SKYPE_PROTONAME, hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)dwChat, 0); + else if (!strcmp(pargs->szArg, "CANCELLED")) + ProtoBroadcastAck(SKYPE_PROTONAME, hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)dwChat, 0); + else if (!strcmp(pargs->szArg, "COMPLETED")) { + // Check if all transfers from this message are completed. + char *pszMsgNum, *pszStatus; + BOOL bAllComplete=TRUE; + char *pszXferIDs = SkypeGetErr("CHATMESSAGE", pszChat, "FILETRANSFERS"); + if (pszXferIDs) { + for (pszMsgNum = strtok(pszXferIDs, ", "); pszMsgNum; pszMsgNum = strtok(NULL, ", ")) { + if (pszStatus=SkypeGetErrID("FILETRANSFER", pszMsgNum, "STATUS")) { + if (strcmp(pszStatus, "COMPLETED")) bAllComplete=FALSE; + free(pszStatus); + if (!bAllComplete) break; + } + } + free(pszXferIDs); + if (bAllComplete) { + ProtoBroadcastAck(SKYPE_PROTONAME, hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)dwChat, 0); + // We could free pEntry at this point, but Garbage Collector will take care of it anyway + } + } + } + } else { + // BYTESTRANSFERRED + PROTOFILETRANSFERSTATUS pfts={0}; + char *pszMsgNum; + int i; + + // This always needs some fetching to fill PFTS :/ + char *pszXferIDs = SkypeGetErr("CHATMESSAGE", pszChat, "FILETRANSFERS"); + if (pszXferIDs) { + for (pszMsgNum = strtok(pszXferIDs, ", "),i=0; pszMsgNum; pszMsgNum = strtok(NULL, ", "),i++) { + DWORD dwTransferred; + BOOL bIsCurFil = strcmp(pargs->szNum,pszMsgNum)==0; + + if (bIsCurFil) + pfts.currentFileNumber = i; + char *pszcbFile = SkypeGetErr("FILETRANSFER", pszMsgNum, "FILESIZE"); + if (pszcbFile) { + dwTransferred = strtoul(pszcbFile, NULL, 10); + pfts.totalBytes+=dwTransferred; + if (bIsCurFil) pfts.currentFileSize=dwTransferred; + free(pszcbFile); + } + if (pszcbFile = SkypeGetErrID("FILETRANSFER", pszMsgNum, "BYTESTRANSFERRED")) { + dwTransferred = strtoul(pszcbFile, NULL, 10); + pfts.totalProgress+=dwTransferred; + if (bIsCurFil) pfts.currentFileProgress=dwTransferred; + free(pszcbFile); + } + } + free(pszXferIDs); + PROTOFILETRANSFERSTATUS *pftsv2 = (PROTOFILETRANSFERSTATUS*)pEntry->pfts; + + pftsv2->currentFileNumber = pfts.currentFileNumber; + pftsv2->totalBytes = pfts.totalBytes; + pftsv2->totalProgress = pfts.totalProgress; + pftsv2->currentFileSize = pfts.currentFileSize; + pftsv2->currentFileProgress = pfts.currentFileProgress; + pftsv2->szCurrentFile = pftsv2->pszFiles[pftsv2->currentFileNumber]; + ProtoBroadcastAck(SKYPE_PROTONAME, hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)dwChat, (LPARAM)pEntry->pfts); + } + } + free(pszChat); + free(pargs); +} + +BOOL FXHandleMessage(const char *pszMsg) +{ + ft_args args={0}; + + const char *pTok=strchr(pszMsg, ' '); + if (!pTok) + return FALSE; + + strncpy(args.szNum, pszMsg, pTok-pszMsg); + pszMsg=pTok+1; + if (!(pTok=strchr(pszMsg, ' '))) return FALSE; + pTok++; + if (!(args.bStatus=!strncmp(pszMsg, "STATUS", 6)) && strncmp(pszMsg, "BYTESTRANSFERRED", 16)) + return FALSE; + ft_args *pargs=(ft_args*)malloc(sizeof(args)); + if (!pargs) return TRUE; + strncpy(args.szArg, pTok, sizeof(args.szArg)); + memcpy(pargs, &args, sizeof(args)); + pthread_create((pThreadFunc)FXHandleMessageThread, pargs); + return TRUE; +} + diff --git a/protocols/SkypeClassic/src/filexfer.h b/protocols/SkypeClassic/src/filexfer.h new file mode 100644 index 0000000000..e35f26e900 --- /dev/null +++ b/protocols/SkypeClassic/src/filexfer.h @@ -0,0 +1,9 @@ +#include "skype.h" +INT_PTR SkypeRecvFile(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeFileAllow(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeFileCancel(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam); + +BOOL FXHandleRecv(PROTORECVEVENT *pre, MCONTACT hContact); +BOOL FXHandleMessage(const char *pszMsg); +void FXFreePFTS(void *pfts); diff --git a/protocols/SkypeClassic/src/gchat.cpp b/protocols/SkypeClassic/src/gchat.cpp index a8ececab4a..c89f79b4e2 100644 --- a/protocols/SkypeClassic/src/gchat.cpp +++ b/protocols/SkypeClassic/src/gchat.cpp @@ -6,10 +6,6 @@ #include "utf8.h" #include "pthread.h" -#include -#include -#include -#include #ifndef DWLP_USER #define DWLP_USER DWL_USER @@ -26,7 +22,6 @@ extern HANDLE hInitChat; extern HINSTANCE hInst; extern char protocol, g_szProtoName[]; -extern DWORD mirandaVersion; static gchat_contacts *chats=NULL; static int chatcount=0; @@ -46,11 +41,13 @@ static CRITICAL_SECTION m_GCMutex; NULL on failure (not enough memory) */ gchat_contacts *GetChat(const TCHAR *szChatId) { - int i; + for (int i=0;i=0 = Number of found item */ static int ExistsChatContact(gchat_contacts *gc, const TCHAR *who) { - int i; - - for (i=0;imJoinedCount;i++) - if (_tcscmp(gc->mJoinedContacts[i].who, who)==0) return i; + for (int i=0;imJoinedCount;i++) + if (_tcscmp(gc->mJoinedContacts[i].who, who)==0) + return i; return -1; } @@ -114,8 +110,10 @@ static int AddChatContact(gchat_contacts *gc, char *who, TCHAR *pszRole) return -2; int i = ExistsChatContact(gc, twho); - if (i >= 0) + if (i >= 0) { + free_nonutf_tchar_string(twho); return i; + } MCONTACT hContact = find_contact(who); @@ -147,7 +145,7 @@ static int AddChatContact(gchat_contacts *gc, char *who, TCHAR *pszRole) } } if (ci.pszVal) mir_free (ci.pszVal); - free_nonutf_tchar_string (twho); + free_nonutf_tchar_string(twho); return i; } @@ -181,7 +179,6 @@ MCONTACT find_chat(LPCTSTR chatname) { return NULL; } -#ifdef _UNICODE MCONTACT find_chatA(char *chatname) { for (MCONTACT hContact=db_find_first(SKYPE_PROTONAME);hContact != NULL;hContact=db_find_next(hContact,SKYPE_PROTONAME)) { if (db_get_b(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==1) @@ -197,7 +194,6 @@ MCONTACT find_chatA(char *chatname) { } return NULL; } -#endif @@ -240,11 +236,13 @@ int __cdecl AddMembers(char *szSkypeMsg) { i=AddChatContact(gc, who, ptszRole); free_nonutf_tchar_string (ptszRole); if (pszRole) free (pszRole); - if (!(contactmask= (unsigned char *) realloc(contactmask, gc->mJoinedCount))) { + BYTE *pcontactmask = (BYTE *) realloc(contactmask, gc->mJoinedCount); + if (!pcontactmask) { iRet = -1; free (who); break; } + contactmask = pcontactmask; contactmask[i]=TRUE; } free (who); @@ -261,10 +259,12 @@ int __cdecl AddMembers(char *szSkypeMsg) { } if (strcmp(who, dbv2.pszVal)) { i=AddChatContact(gc, who, NULL); - if (i<0 || !(contactmask= (unsigned char *) realloc(contactmask, gc->mJoinedCount))) { + BYTE *pcontactmask; + if (i<0 || !(pcontactmask= (BYTE *) realloc(contactmask, gc->mJoinedCount))) { iRet = -1; break; } + contactmask = pcontactmask; contactmask[i]=TRUE; } } @@ -372,14 +372,11 @@ int __cdecl ChatInit(WPARAM wParam, LPARAM lParam) char *szChatName = SkypeGet ("CHAT", (char *)wParam, "FRIENDLYNAME"); if (!szChatName || !*szChatName) - gcw.ptszName=TranslateT("Unknown"); else { -#ifdef _UNICODE + gcw.ptszName=TranslateT("Unknown"); + else { gcw.ptszName=make_unicode_string((const unsigned char*)szChatName); free (szChatName); szChatName = (char*)gcw.ptszName; -#else - gcw.ptszName=szChatName; -#endif } gcw.ptszID = make_nonutf_tchar_string((const unsigned char*)wParam); gcw.ptszStatusbarText = NULL; @@ -409,12 +406,8 @@ int __cdecl ChatInit(WPARAM wParam, LPARAM lParam) if (protocol >=7 && (szChatRole = SkypeGet ("CHAT", (char *)wParam, "MYROLE"))) { if (strncmp(szChatRole, "ERROR", 5)) { -#ifdef _UNICODE gce.ptszStatus = make_unicode_string((const unsigned char*)szChatRole); free (szChatRole); -#else - gce.ptszStatus = szChatRole; -#endif } } if (!gce.ptszStatus) gce.ptszStatus=_tcsdup(_T("CREATOR")); @@ -576,11 +569,7 @@ void SetChatTopic(const TCHAR *szChatId, TCHAR *szTopic, BOOL bSet) CallService(MS_GC_EVENT, 0, (LPARAM)&gce); if (bSet) { -#ifdef _UNICODE szUTFTopic=(char*)make_utf8_string(szTopic); -#else - if (utf8_encode(szTopic, &szUTFTopic)==-1) szUTFTopic = NULL; -#endif if (szUTFTopic) { SkypeSend ("ALTER CHAT "STR" SETTOPIC %s", szChatId, szUTFTopic); free (szUTFTopic); @@ -635,27 +624,11 @@ int GCEventHook(WPARAM,LPARAM lParam) { *pEnd==_T('\r') || *pEnd==_T('\n'); pEnd--) *pEnd=0; // Send message to the chat-contact if (ccs.hContact = find_chat(gch->pDest->ptszID)) { -#ifdef _UNICODE // If PREF_UTF is supported, just convert it to UTF8 and pass the buffer to PSS_MESSAGE - if (mirandaVersion >= 0x070000) { - ccs.lParam = (LPARAM)make_utf8_string(gch->ptszText); - ccs.wParam = PREF_UTF; - CallProtoService (SKYPE_PROTONAME, PSS_MESSAGE, 0, (LPARAM)&ccs); - free ((void*)ccs.lParam); - } else { - // Otherwise create this strange dual miranda-format - ccs.lParam = (LPARAM)calloc(3, _tcslen(gch->ptszText)+1); - wcstombs ((char*)ccs.lParam, gch->ptszText, _tcslen(gch->ptszText)+1); - _tcscpy ((TCHAR*)((char*)ccs.lParam+strlen((char*)ccs.lParam)+1), gch->ptszText); - ccs.wParam = PREF_UNICODE; - CallProtoService (SKYPE_PROTONAME, PSS_MESSAGE, 0, (LPARAM)&ccs); - free ((void*)ccs.lParam); - } -#else - ccs.lParam = (LPARAM)gch->ptszText; - ccs.wParam = PREF_TCHAR; + ccs.lParam = (LPARAM)make_utf8_string(gch->ptszText); + ccs.wParam = PREF_UTF; CallProtoService (SKYPE_PROTONAME, PSS_MESSAGE, 0, (LPARAM)&ccs); -#endif + free ((void*)ccs.lParam); } // Add our line to the chatlog diff --git a/protocols/SkypeClassic/src/msglist.cpp b/protocols/SkypeClassic/src/msglist.cpp index aedb4d1257..9ba9b67679 100644 --- a/protocols/SkypeClassic/src/msglist.cpp +++ b/protocols/SkypeClassic/src/msglist.cpp @@ -3,6 +3,7 @@ #include "memlist.h" #include "debug.h" #include "msglist.h" +#include "filexfer.h" #define MSGLIST_TIMEOUT 1800 // Chatmessage references will be kept for 30 minutes @@ -18,9 +19,19 @@ void MsgList_Init(void) m_hMsgList = List_Init(128); } +void MsgList_FreeEntry(TYP_MSGLENTRY *pEntry) +{ + if (pEntry->pfts) + FXFreePFTS(pEntry->pfts); + HeapFree(GetProcessHeap(), 0, pEntry); +} + void MsgList_Exit(void) { if (!m_hMsgList) return; + TYP_MSGLENTRY *pEntry; + while (pEntry = (TYP_MSGLENTRY*) List_Pop(m_hMsgList)) + MsgList_FreeEntry(pEntry); List_FreeElements (m_hMsgList); List_Exit(m_hMsgList); m_hMsgList = NULL; @@ -33,7 +44,7 @@ TYP_MSGLENTRY *MsgList_Add(DWORD uMsgNum, HANDLE hEvent) BOOL bFound; LOG (("MsgList_Add (%d, %08X)", uMsgNum, hEvent)); - if (!m_hMsgList || !hEvent) return FALSE; + if (!m_hMsgList) return FALSE; bFound = List_BinarySearch(m_hMsgList,CmpProc,(void *)uMsgNum,&iListInd); if (!bFound) pEntry = (TYP_MSGLENTRY*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYP_MSGLENTRY)); else pEntry = (TYP_MSGLENTRY*)List_ElementAt (m_hMsgList, iListInd); @@ -78,8 +89,7 @@ void MsgList_CollectGarbage(void) if (pEntry->t < t) { LOG (("MsgList_CollectGarbage throwing out msg %d", pEntry->uMsgNum)); - HeapFree (GetProcessHeap(), 0, List_RemoveElementAt (m_hMsgList, i)); - i--; + MsgList_FreeEntry((TYP_MSGLENTRY*)List_RemoveElementAt(m_hMsgList, i--)); } } } diff --git a/protocols/SkypeClassic/src/msglist.h b/protocols/SkypeClassic/src/msglist.h index 66a271ef18..94316c703e 100644 --- a/protocols/SkypeClassic/src/msglist.h +++ b/protocols/SkypeClassic/src/msglist.h @@ -6,6 +6,7 @@ typedef struct { HANDLE hMetaEvent; time_t t; time_t tEdited; + void *pfts; } TYP_MSGLENTRY; void MsgList_Init(void); diff --git a/protocols/SkypeClassic/src/resource.h b/protocols/SkypeClassic/src/resource.h index 427289efde..d80e5ce87c 100644 --- a/protocols/SkypeClassic/src/resource.h +++ b/protocols/SkypeClassic/src/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Skript1.rc +// Microsoft Visual C++ generated include file. +// Used by ..\res\Resource.rc // #define IDI_SKYPE 102 #define IDI_ONLINE 104 @@ -112,6 +112,7 @@ #define IDC_STATIC_POPUPBACKCOLORERR 1069 #define IDC_STATIC_PATHINFO 1070 #define IDC_STATIC_RESTART 1071 +#define IDC_NOACK 1072 // Next default values for new objects // @@ -119,7 +120,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 183 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1072 +#define _APS_NEXT_CONTROL_VALUE 1073 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/protocols/SkypeClassic/src/skype.cpp b/protocols/SkypeClassic/src/skype.cpp index 2427a8a29d..aa1b3b5afd 100644 --- a/protocols/SkypeClassic/src/skype.cpp +++ b/protocols/SkypeClassic/src/skype.cpp @@ -28,17 +28,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "m_toptoolbar.h" #include "msglist.h" #include "memlist.h" +#include "filexfer.h" #include -#ifndef INVALID_FILE_ATTRIBUTES -#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF -#endif #ifdef _WIN64 #if (_MSC_VER < 1500) #pragma comment (lib, "bufferoverflowU.lib") #endif #endif -#pragma warning (disable: 4706) // assignment within conditional expression POPUPDATAT MessagePopup; @@ -46,7 +43,7 @@ POPUPDATAT MessagePopup; HWND hSkypeWnd = NULL, g_hWnd = NULL, hSkypeWndSecondary = NULL, hForbiddenSkypeWnd = NULL; HANDLE SkypeReady, SkypeMsgReceived, hInitChat = NULL, httbButton = NULL, FetchMessageEvent = NULL; BOOL SkypeInitialized = FALSE, MirandaShuttingDown = FALSE, PopupServiceExists = FALSE; -BOOL UseSockets = FALSE, bSkypeOut = FALSE, bProtocolSet = FALSE, bIsImoproxy = FALSE; +BOOL UseSockets = FALSE, bSkypeOut = FALSE, bProtocolSet = FALSE, bIsImoproxy = FALSE, bHasFileXfer = FALSE; char skype_path[MAX_PATH], protocol = 2, *pszProxyCallout = NULL, g_szProtoName[_MAX_FNAME] = "SkypeClassic"; int SkypeStatus = ID_STATUS_OFFLINE, hSearchThread = -1, receivers = 1; long sendwatchers = 0, rcvwatchers = 0; @@ -55,7 +52,6 @@ LONG AttachStatus = -1; HINSTANCE hInst; HANDLE hProtocolAvatarsFolder; char DefaultAvatarsFolder[MAX_PATH + 1]; -DWORD mirandaVersion; int hLangpack = 0; CRITICAL_SECTION RingAndEndcallMutex, QueryThreadMutex, TimeMutex; @@ -117,6 +113,7 @@ typedef struct { BOOL bIsRead; BOOL bDontMarkSeen; BOOL QueryMsgDirection; + BOOL bUseTimestamp; TYP_MSGLENTRY *pMsgEntry; } fetchmsg_arg; @@ -125,6 +122,15 @@ typedef struct { char szId[16]; } msgsendwt_arg; +#ifdef USE_REAL_TS +typedef struct { + MCONTACT hContact; + time_t timestamp; +} arg_dbaddevent; +arg_dbaddevent m_AddEventArg = {0}; +CRITICAL_SECTION AddEventMutex; +#endif + /* * visual styles support (XP+) * returns 0 on failure @@ -194,7 +200,6 @@ PLUGININFOEX pluginInfo = { */ int ShowMessage(int iconID, TCHAR *lpzText, int mustShow) { if (db_get_b(NULL, SKYPE_PROTONAME, "SuppressErrors", 0)) return -1; - lpzText = TranslateTS(lpzText); if (bModulesLoaded && PopupServiceExists && ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, SKYPE_PROTONAME, "UsePopup", 0) && !MirandaShuttingDown) { BOOL showPopup, popupWindowColor; @@ -233,7 +238,7 @@ int ShowMessage(int iconID, TCHAR *lpzText, int mustShow) { return 0; } } -#ifdef _UNICODE + int ShowMessageA(int iconID, char *lpzText, int mustShow) { WCHAR *lpwText; int iRet; @@ -244,7 +249,6 @@ int ShowMessageA(int iconID, char *lpzText, int mustShow) { free(lpwText); return iRet; } -#endif // processing Hooks @@ -451,7 +455,7 @@ int SearchFriends(void) { if (SkypeSend("SEARCH FRIENDS") != -1 && (ptr = SkypeRcvTime("USERS", st, INFINITE))) { if (strncmp(ptr, "ERROR", 5)) { - if (ptr + 5) { + if (ptr[5]) { for (token = strtok_r(ptr + 5, ", ", &nextoken); token; token = strtok_r(NULL, ", ", &nextoken)) { if (!(pStat = SkypeGet("USER", token, "ONLINESTATUS"))) { @@ -640,8 +644,6 @@ void __cdecl SkypeSystemInit(char *dummy) { memmove(pszUser, pszUser + 18, strlen(pszUser + 17)); if (_stricmp(dbv.pszVal, pszUser)) { - char szError[256]; - // Doesn't match, maybe we have a second Skype instance we have to take // care of? If in doubt, let's wait a while for it to report its hWnd to us. LOG(("Userhandle %s doesn't match username %s from settings", pszUser, dbv.pszVal)); @@ -676,10 +678,10 @@ void __cdecl SkypeSystemInit(char *dummy) { if (hForbiddenSkypeWnd == hSkypeWnd && !hSkypeWndSecondary) { int oldstatus; - - sprintf(szError, "Username '%s' provided by Skype API doesn't match username '%s' in " + char szError[256]; + sprintf(szError, Translate("Username '%s' provided by Skype API doesn't match username '%s' in " "your settings. Please either remove username setting in you configuration or correct " - "it. Will not connect!", pszUser, dbv.pszVal); + "it. Will not connect!"), pszUser, dbv.pszVal); OUTPUTA(szError); Initializing = FALSE; AttachStatus = -1; @@ -717,7 +719,16 @@ void __cdecl SkypeSystemInit(char *dummy) { if (protocol >= 5 || bIsImoproxy) { SkypeSend("CREATE APPLICATION libpurple_typing"); testfor("CREATE APPLICATION libpurple_typing", 2000); + char *pszErr; + if (SkypeSend("#FT FILE") == 0 && (pszErr = SkypeRcvTime("#FT ERROR", SkypeTime(NULL), 1000))) + { + bHasFileXfer = !strncmp(pszErr+4, "ERROR 510", 9); + free(pszErr); + } } + else + bHasFileXfer = FALSE; + if (protocol >= 5) { SearchUsersWaitingMyAuthorization(); if (db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0)) @@ -766,7 +777,7 @@ void FirstLaunch(char *) { LOG(("Test #%d", counter)); if (SkypeSend("PING") == -1) counter++; else break; if (counter >= 20) { - OUTPUT(_T("Cannot reach Skype API, plugin disfunct.")); + OUTPUT(TranslateT("Cannot reach Skype API, plugin disfunct.")); LOG(("FirstLaunch thread stopped: cannot reach Skype API.")); return; } @@ -813,7 +824,7 @@ int OnModulesLoaded(WPARAM, LPARAM) { gcr.ptszDispName = _T("Skype protocol"); gcr.pszModule = SKYPE_PROTONAME; if (CallService(MS_GC_REGISTER, 0, (LPARAM)&gcr)) - OUTPUT(_T("Unable to register with Groupchat module!")); + OUTPUT(TranslateT("Unable to register with Groupchat module!")); _snprintf(szEvent, sizeof(szEvent), "%s\\ChatInit", SKYPE_PROTONAME); hInitChat = CreateHookableEvent(szEvent); @@ -875,14 +886,21 @@ void FetchMessageThread(fetchmsg_arg *pargs) { // Get Timestamp if (!args.pMsgEntry || !args.pMsgEntry->tEdited) { - if (!(ptr = SkypeGet(cmdMessage, args.msgnum, "TIMESTAMP"))) return; - if (strncmp(ptr, "ERROR", 5)) { - timestamp = atol(ptr); - // Ensure time correction on clock skew... - if (timestamp>(DWORD)SkypeTime(NULL)) timestamp = (DWORD)SkypeTime(NULL); + timestamp=(DWORD)SkypeTime(NULL); + /* We normally don't use the real timestamp, if it's not history import. + * Why? -> Because if you are sending a message while there are still + * incoming messages that get processed, msgs are inserted into the + * DB with correct timestamp, but message sending dialog shows garbled + * messages then because he cannot deal with the situation of incoming + * messages that are prior to last sent message */ +#ifndef USE_REAL_TS + if (args.bUseTimestamp) +#endif + { + if (!(ptr=SkypeGet (cmdMessage, args.msgnum, "TIMESTAMP"))) return; + if (strncmp(ptr, "ERROR", 5)) timestamp=atol(ptr); + free(ptr); } - else timestamp = (DWORD)SkypeTime(NULL); - free(ptr); } else timestamp = (DWORD)(args.pMsgEntry->tEdited); @@ -1129,6 +1147,16 @@ void FetchMessageThread(fetchmsg_arg *pargs) { hContact = add_contact(who, PALF_TEMPORARY); } } + + if (strcmp(type, "FILETRANSFER") == 0) + { + // Our custom Skypekit FILETRANSFER extension + bHasFileXfer = TRUE; + pre.timestamp = timestamp; + FXHandleRecv(&pre, hContact); + __leave; + } + // Text which was sent (on edited msg, BODY may already be in queue, check) sprintf(szBuf, "GET %s %s BODY", cmdMessage, args.msgnum); if (!args.pMsgEntry || !args.pMsgEntry->tEdited || !(ptr = SkypeRcv(szBuf + 4, 1000))) @@ -1181,8 +1209,7 @@ void FetchMessageThread(fetchmsg_arg *pargs) { if (pszUTFnick) free(pszUTFnick); } - if (mirandaVersion >= 0x070000 && // 0.7.0+ supports PREF_UTF flag, no need to decode UTF8 - !isGroupChat) { // I guess Groupchat doesn't support UTF8? + if (!isGroupChat) { // I guess Groupchat doesn't support UTF8? msg = ptr; pre.flags |= PREF_UTF; } @@ -1369,15 +1396,14 @@ void MessageListProcessingThread(char *str) { char *token, *nextoken, *chat = NULL; fetchmsg_arg *args; TYP_LIST *hListMsgs = List_Init(32); - int i, nCount; // Frst we need to sort the message timestamps - for ((token = strtok_r(str, ", ", &nextoken)); token; token = strtok_r(NULL, ", ", &nextoken)) { + for ((token = strtok_r(str+1, ", ", &nextoken)); token; token = strtok_r(NULL, ", ", &nextoken)) { if (args = (fetchmsg_arg*)calloc(1, sizeof(fetchmsg_arg) + sizeof(DWORD))) { strncpy(args->msgnum, token, sizeof(args->msgnum)); args->getstatus = TRUE; - args->bIsRead = TRUE; - args->bDontMarkSeen = TRUE; + args->bIsRead = *str; + args->bDontMarkSeen = *str; args->QueryMsgDirection = TRUE; args->pMsgEntry = (TYP_MSGLENTRY*)SkypeGet("CHATMESSAGE", token, "TIMESTAMP"); if (!chat) chat = SkypeGet("CHATMESSAGE", token, "CHATNAME"); @@ -1385,10 +1411,12 @@ void MessageListProcessingThread(char *str) { else free(args); } } - for (i = 0, nCount = List_Count(hListMsgs); i < nCount; i++) { + int nCount = List_Count(hListMsgs); + for (int i = 0; i < nCount; i++) { args = (fetchmsg_arg*)List_ElementAt(hListMsgs, i); free(args->pMsgEntry); args->pMsgEntry = NULL; + args->bUseTimestamp = TRUE; FetchMessageThreadSync(args); } if (chat) { @@ -1880,7 +1908,7 @@ LRESULT APIENTRY WndProc(HWND hWndDlg, UINT message, UINT wParam, LONG lParam) } } else if (!strcmp(ptr, "BIRTHDAY")) { - unsigned int y, m, d; + int y, m, d; if (sscanf(ptr + 9, "%04d%02d%02d", &y, &m, &d) == 3) { db_set_w(hContact, SKYPE_PROTONAME, "BirthYear", (WORD)y); db_set_b(hContact, SKYPE_PROTONAME, "BirthMonth", (BYTE)m); @@ -2054,11 +2082,14 @@ LRESULT APIENTRY WndProc(HWND hWndDlg, UINT message, UINT wParam, LONG lParam) } *ptr = ' '; } - else - if (strncmp(ptr, " CHATMESSAGES ", 14) == 0) { - pthread_create((pThreadFunc)MessageListProcessingThread, _strdup(ptr + 14)); - break; - } + else if (strncmp(ptr, " CHATMESSAGES ", 14) == 0) { + int iLen=strlen(ptr+14)+1; + char *pParam=(char*)calloc(iLen+1, 1); + *pParam=TRUE; + memcpy(pParam+1, ptr+14, iLen); + pthread_create((pThreadFunc)MessageListProcessingThread, pParam); + break; + } } } if (!strncmp(szSkypeMsg, "CALL ", 5)) { @@ -2108,14 +2139,18 @@ LRESULT APIENTRY WndProc(HWND hWndDlg, UINT message, UINT wParam, LONG lParam) break; } if (!strncmp(szSkypeMsg, "MESSAGES", 8) || !strncmp(szSkypeMsg, "CHATMESSAGES", 12)) { - if (strlen(szSkypeMsg) <= (UINT)(strchr(szSkypeMsg, ' ') - szSkypeMsg + 1)) + char *pMsgs; + int iLen; + if (strlen(szSkypeMsg) <= (UINT)((pMsgs=strchr(szSkypeMsg, ' ')) - szSkypeMsg + 1)) { LOG(("%s %d %s %d", szSkypeMsg, (UINT)(strchr(szSkypeMsg, ' ') - szSkypeMsg + 1), strchr(szSkypeMsg, ' '), strlen(szSkypeMsg))); break; } LOG(("MessageListProcessingThread launched")); - pthread_create((pThreadFunc)MessageListProcessingThread, _strdup(strchr(szSkypeMsg, ' ') + 1)); + char *pParam=(char*)calloc((iLen=strlen(pMsgs)+1)+1, 1); + memcpy(pParam+1, pMsgs, iLen); + pthread_create((pThreadFunc)MessageListProcessingThread, pParam); break; } if (!strncmp(szSkypeMsg, "MESSAGE", 7) || !strncmp(szSkypeMsg, "CHATMESSAGE", 11)) @@ -2149,6 +2184,8 @@ LRESULT APIENTRY WndProc(HWND hWndDlg, UINT message, UINT wParam, LONG lParam) } } } + if (bHasFileXfer && !strncmp(szSkypeMsg, "FILETRANSFER", 12)) + FXHandleMessage(szSkypeMsg+13); if (!strncmp(szSkypeMsg, "ERROR 68", 8)) { LOG(("We got a sync problem :( -> SendMessage() will try to recover...")); break; @@ -2595,7 +2632,22 @@ INT_PTR SkypeBasicSearch(WPARAM, LPARAM lParam) { return (hSearchThread = pthread_create((pThreadFunc)BasicSearchThread, _strdup((char *)lParam))); } +#ifdef USE_REAL_TS +static INT_PTR EventAddHook(WPARAM wParam, LPARAM lParam) +{ + MCONTACT hContact = (MCONTACT)wParam; + DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; + if (dbei && hContact == m_AddEventArg.hContact && dbei->eventType==EVENTTYPE_MESSAGE && (dbei->flags & DBEF_SENT) && + strcmp(dbei->szModule, SKYPE_PROTONAME) == 0) { + dbei->timestamp = m_AddEventArg.timestamp; + } + return 0; +} +#endif + void MessageSendWatchThread(void *a) { + char *err, *ptr, *nexttoken; + HANDLE hDBAddEvent = NULL; msgsendwt_arg *arg = (msgsendwt_arg*)a; LOG(("MessageSendWatchThread started.")); @@ -2605,8 +2657,7 @@ void MessageSendWatchThread(void *a) { if (str) { if (!db_get_b(arg->hContact, SKYPE_PROTONAME, "ChatRoom", 0)) { - char *err = GetSkypeErrorMsg(str); - if (err) { + if (err = GetSkypeErrorMsg(str)) { ProtoBroadcastAck(SKYPE_PROTONAME, arg->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)1, (LPARAM)Translate(err)); free(err); free(str); @@ -2614,7 +2665,31 @@ void MessageSendWatchThread(void *a) { LOG(("MessageSendWatchThread terminated.")); return; } + /* The USE_REAL_TS code would correct our Sent-Timestamp to the real time that the + * event was sent according to the clock of the machine Skype is running on. + * However msg-Dialog has problems with this. + */ +#ifdef USE_REAL_TS + EnterCriticalSection(&AddEventMutex); +#endif + if ((ptr=strtok_r(str, " ", &nexttoken)) && (*ptr!='#' || (ptr=strtok_r(NULL, " ", &nexttoken))) && + (ptr=strtok_r(NULL, " ", &nexttoken))) { + /* Use this to ensure that main thread doesn't pick up sent message */ + MsgList_Add(strtoul(ptr, NULL, 10), INVALID_HANDLE_VALUE); +#ifdef USE_REAL_TS + if (err=SkypeGet (cmdMessage, ptr, "TIMESTAMP")) { + m_AddEventArg.hContact = arg->hContact; + m_AddEventArg.timestamp = atoi(err); + free(err); + hDBAddEvent = HookEvent(ME_DB_EVENT_FILTER_ADD,EventAddHook); + } +#endif + } ProtoBroadcastAck(SKYPE_PROTONAME, arg->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)1, 0); +#ifdef USE_REAL_TS + if (hDBAddEvent) UnhookEvent(hDBAddEvent); + LeaveCriticalSection(&AddEventMutex); +#endif } free(str); LOG(("MessageSendWatchThread terminated gracefully.")); @@ -2662,14 +2737,20 @@ INT_PTR SkypeSendMessage(WPARAM, LPARAM lParam) { db_free(&dbv); if (sendok) { - msgsendwt_arg *psendarg = (msgsendwt_arg*)calloc(1, sizeof(msgsendwt_arg)); + if (db_get_b(NULL, SKYPE_PROTONAME, "NoAck", 0)) { + ProtoBroadcastAck(SKYPE_PROTONAME, ccs->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)1, 0); + } + else { + msgsendwt_arg *psendarg = (msgsendwt_arg*)calloc(1, sizeof(msgsendwt_arg)); - if (psendarg) { - psendarg->hContact = ccs->hContact; - strcpy(psendarg->szId, szId); - pthread_create(MessageSendWatchThread, psendarg); + if (psendarg) { + psendarg->hContact = ccs->hContact; + strcpy(psendarg->szId, szId); + pthread_create(MessageSendWatchThread, psendarg); + return 1; + } + InterlockedDecrement(&sendwatchers); } - else InterlockedDecrement(&sendwatchers); return 1; } else InterlockedDecrement(&sendwatchers); @@ -2843,7 +2924,7 @@ void CleanupNicknames(char *) { } } } - OUTPUT(_T("Cleanup finished.")); + OUTPUT(TranslateT("Cleanup finished.")); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -3012,7 +3093,7 @@ void __cdecl MsgPump(char *) LOG(("Created Dispatch window with handle %08X", (long)g_hWnd)); if (!g_hWnd) { - OUTPUT(_T("Cannot create window.")); + OUTPUT(TranslateT("Cannot create window.")); TellError(GetLastError()); SetEvent(MessagePumpReady); return; @@ -3035,8 +3116,6 @@ void __cdecl MsgPump(char *) extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) { - mirandaVersion = mirVersion; - return &pluginInfo; } @@ -3071,6 +3150,9 @@ extern "C" int __declspec(dllexport) Load(void) InitializeCriticalSection(&RingAndEndcallMutex); InitializeCriticalSection(&QueryThreadMutex); InitializeCriticalSection(&TimeMutex); +#ifdef USE_REAL_TS + InitializeCriticalSection(&AddEventMutex); +#endif #ifdef _DEBUG @@ -3087,7 +3169,7 @@ extern "C" int __declspec(dllexport) Load(void) // Mutex is also initialized here. LOG(("SkypeMsgInit initializing Skype MSG-queue")); if (SkypeMsgInit() == -1) { - OUTPUT(_T("Memory allocation error on startup.")); + OUTPUT(TranslateT("Memory allocation error on startup.")); return 0; } @@ -3138,7 +3220,7 @@ extern "C" int __declspec(dllexport) Load(void) // Start Skype connection if (!(ControlAPIAttach = RegisterWindowMessage(_T("SkypeControlAPIAttach"))) || !(ControlAPIDiscover = RegisterWindowMessage(_T("SkypeControlAPIDiscover")))) { - OUTPUT(_T("Cannot register Window message.")); + OUTPUT(TranslateT("Cannot register Window message.")); return 0; } @@ -3150,7 +3232,7 @@ extern "C" int __declspec(dllexport) Load(void) #endif !(hBuddyAdded = CreateEvent(NULL, FALSE, FALSE, NULL)) || !(FetchMessageEvent = CreateEvent(NULL, FALSE, TRUE, NULL))) { - OUTPUT(_T("Unable to create Mutex!")); + OUTPUT(TranslateT("Unable to create Mutex!")); return 0; } @@ -3227,6 +3309,9 @@ extern "C" int __declspec(dllexport) Unload(void) LOG(("Unload: Shutdown complete")); #ifdef _DEBUG end_debug(); +#endif +#ifdef USE_REAL_TS + DeleteCriticalSection(&AddEventMutex); #endif DeleteCriticalSection(&TimeMutex); return 0; diff --git a/protocols/SkypeClassic/src/skype.h b/protocols/SkypeClassic/src/skype.h index b6c929875b..4619d62706 100644 --- a/protocols/SkypeClassic/src/skype.h +++ b/protocols/SkypeClassic/src/skype.h @@ -42,30 +42,11 @@ #include #include #include -#include - -// MyDetails defines - -// wParam=NULL -// lParam=(char *) new nickname - do not free -// return=0 for sucess -#define PS_SETMYNICKNAME "/SetNickname" - -// Optional, default value is 1024 -// wParam=NULL -// lParam=NULL -// return= <=0 for error, >0 the max length of the nick -#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength" - -// wParam=(char *)Buffer to file name -// lParam=(int)Buffer size -// return=0 for sucess -#define PS_GETMYAVATAR "/GetMyAvatar" +#include +#include +#include +#include -// wParam=0 -// lParam=(const char *)Avatar file name -// return=0 for sucess -#define PS_SETMYAVATAR "/SetMyAvatar" // Program defines @@ -84,7 +65,7 @@ typedef struct { char ChatNew[MAXMODULELABELLENGTH]; char SetAvatar[MAXMODULELABELLENGTH]; - char SendFile[MAXMODULELABELLENGTH]; + char SendGuiFile[MAXMODULELABELLENGTH]; char HoldCall[MAXMODULELABELLENGTH]; char AnswerCall[MAXMODULELABELLENGTH]; char ImportHistory[MAXMODULELABELLENGTH]; @@ -101,7 +82,7 @@ typedef struct { #define SKYPE_IMPORTHISTORY g_svcNames.ImportHistory #define SKYPE_ANSWERCALL g_svcNames.AnswerCall #define SKYPE_HOLDCALL g_svcNames.HoldCall -#define SKYPE_SENDFILE g_svcNames.SendFile +#define SKYPE_SENDFILE g_svcNames.SendGuiFile #define SKYPE_SETAVATAR g_svcNames.SetAvatar #define SKYPE_CHATNEW g_svcNames.ChatNew #define SKYPE_BLOCKCONTACT g_svcNames.BlockContact @@ -134,11 +115,7 @@ void PingPong(void); void CheckIfApiIsResponding(char *); void TellError(DWORD err); int ShowMessage(int, TCHAR*, int); -#ifdef _UNICODE int ShowMessageA(int iconID, char *lpzText, int mustShow); -#else -#define ShowMessageA ShowMessage -#endif void EndCallThread(char *); void GetInfoThread(void *); int OnDetailsInit( WPARAM, LPARAM ); diff --git a/protocols/SkypeClassic/src/skypeapi.cpp b/protocols/SkypeClassic/src/skypeapi.cpp index ebc74afeda..0f67db8ee4 100644 --- a/protocols/SkypeClassic/src/skypeapi.cpp +++ b/protocols/SkypeClassic/src/skypeapi.cpp @@ -7,7 +7,7 @@ #include "utf8.h" #include "debug.h" #include "contacts.h" -#include "skypeproxy.h" +#include "skypeproxy/skypeproxy.h" #include "pthread.h" #include "gchat.h" #include "alogon.h" @@ -50,13 +50,14 @@ status_map status_codes[] = { //status_map -static CRITICAL_SECTION ConnectMutex; +static CRITICAL_SECTION ConnectMutex, SendMutex; static BOOL rcvThreadRunning=FALSE, isConnecting = FALSE; static SOCKET ClientSocket=INVALID_SOCKET; static HANDLE SkypeMsgToSend=NULL; static char *m_szSendBuf = NULL; static DWORD m_iBufSize = 0; +static HANDLE m_FileSlots[255]={INVALID_HANDLE_VALUE}; static int _ConnectToSkypeAPI(char *path, BOOL bStart); @@ -78,9 +79,27 @@ INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam) { * Skype via Socket --> Skype2Socket connection */ +static int Recv(SOCKET s, char *buf, int len) { + int ret,cnt=0; + + do + { + if ((ret=recv(s,buf,len,0))==SOCKET_ERROR) { + LOG(("Recv() Socket error")); + return 0; + } + if (ret==0) break; + cnt+=ret; + buf+=ret; + len-=ret; + } while (len); + return len?0:cnt; +} + void rcvThread(char *dummy) { + unsigned char cmd=0, nSlot; unsigned int length; - char *buf; + char *buf=NULL; COPYDATASTRUCT CopyData; int rcv; @@ -92,31 +111,102 @@ void rcvThread(char *dummy) { return; } LOG(("rcvThread Receiving from socket..")); - if ((rcv=recv(ClientSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || rcv==0) { + if (!(rcv=Recv(ClientSocket, (char *)&length, sizeof(length))) || length>0x10000000) { rcvThreadRunning=FALSE; if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} else {LOG(("rcvThread lost connection, graceful shutdown"));} return; } + EnterCriticalSection(&SendMutex); + if (length == 0) { + unsigned short lenfn; + char szFileName[MAX_PATH], *pszUTFFile=NULL; + + // Command mode + if ((rcv = Recv(ClientSocket, (char*)&cmd, sizeof(cmd)))) { + switch (cmd) + { + case OPEN_SLOT: + LOG(("rcvThread OPEN_SLOT")); + if (!(rcv = Recv(ClientSocket, (char*)&lenfn, sizeof(lenfn))) || + !(rcv = Recv(ClientSocket, szFileName, lenfn))) { + LOG(("OPEN_SLOT failed: rcv=%d", rcv)); + rcv=0; + break; + } + + utf8_decode(szFileName, &pszUTFFile); + for (nSlot=0; nSlot=sizeof(m_FileSlots)/sizeof(m_FileSlots[0])) cmd=0; + else { + if ((m_FileSlots[nSlot] = CreateFileA(pszUTFFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) + !=INVALID_HANDLE_VALUE) nSlot++; else nSlot=0; + } + free(pszUTFFile); + LOG(("rcvThread OPEN_SLOT(%s) -> %d", szFileName, nSlot)); + if ((rcv=send(ClientSocket, (char *)&nSlot, sizeof(nSlot), 0)) == SOCKET_ERROR || rcv==0) rcv=0; + else { + LeaveCriticalSection(&SendMutex); + continue; + } + break; + case DATA_SLOT: + LOG(("rcvThread DATA_SLOT")); + if (!(rcv=Recv(ClientSocket, (char*)&nSlot, sizeof(nSlot))) || !nSlot || + !(rcv=Recv(ClientSocket, (char *)&length, sizeof(length))) || length>0x10000000) { + LOG(("DATA_SLOT failed: rcv=%d", rcv)); + rcv=0; + } + break; + case CLOSE_SLOT: + LOG(("rcvThread CLOSE_SLOT")); + if (!(rcv = Recv(ClientSocket, (char*)&nSlot, sizeof(nSlot)))) { + LOG(("CLOSE_SLOT failed: rcv=%d")); + rcv=0; + break; + } + LOG(("rcvThread CLOSE_SLOT(%d)", nSlot)); + CloseHandle(m_FileSlots[nSlot-1]); + m_FileSlots[nSlot-1]=INVALID_HANDLE_VALUE; + if (rcv) { + LeaveCriticalSection(&SendMutex); + continue; + } + break; + } + } + } LOG(("rcvThread Received length, recieving message..")); buf=(char *)calloc(1, length+1); - if ((rcv = recv(ClientSocket, buf, length, 0))==SOCKET_ERROR || rcv==0) { + if (rcv==0 || !(buf=(char *)calloc(1, length+1)) || + !(rcv = Recv(ClientSocket, buf, length))) { rcvThreadRunning=FALSE; - if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} - else {LOG(("rcvThread lost connection, graceful shutdown"));} + LOG(("rcvThread lost connection, graceful shutdown")); free(buf); + LeaveCriticalSection(&SendMutex); return; } - LOG(("Received message: %s", buf)); + if (cmd==DATA_SLOT) { + DWORD dwWritten; - CopyData.dwData=0; - CopyData.lpData=buf; - CopyData.cbData=(DWORD)strlen(buf)+1; - if (!SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, (LPARAM)&CopyData)) - { - LOG(("SendMessage failed: %08X", GetLastError())); + LOG(("Received data packet with %u bytes", length)); + if ((cmd = (char)WriteFile(m_FileSlots[nSlot-1], buf, length, &dwWritten, NULL)) && dwWritten!=length) + cmd=0; + //send(ClientSocket, (char *)&cmd, sizeof(cmd), 0); + } else { + LOG(("Received message: %s", buf)); + + CopyData.dwData=0; + CopyData.lpData=buf; + CopyData.cbData=(DWORD)strlen(buf)+1; + if (!SendMessage(g_hWnd, WM_COPYDATALOCAL, (WPARAM)hSkypeWnd, (LPARAM)&CopyData)) + { + LOG(("SendMessage failed: %08X", GetLastError())); + } } free(buf); + LeaveCriticalSection(&SendMutex); } } @@ -133,12 +223,15 @@ void sendThread(char *dummy) { length=(unsigned int)strlen(szMsg); if (UseSockets) { + EnterCriticalSection(&SendMutex); if (send(ClientSocket, (char *)&length, sizeof(length), 0) != SOCKET_ERROR && send(ClientSocket, szMsg, length, 0) != SOCKET_ERROR) { free (szMsg); + LeaveCriticalSection(&SendMutex); continue; } SendResult = 0; + LeaveCriticalSection(&SendMutex); } else { CopyData.dwData=0; CopyData.lpData=szMsg; @@ -196,7 +289,8 @@ int SkypeMsgInit(void) { MsgQ_Init(&SkypeMsgs); MsgQ_Init(&SkypeSendQueue); - InitializeCriticalSection(&ConnectMutex); + InitializeCriticalSection(&ConnectMutex); + InitializeCriticalSection(&SendMutex); if (SkypeMsgToSend=CreateSemaphore(NULL, 0, MAX_MSGS, NULL)) { if (m_szSendBuf = (char*)malloc(m_iBufSize=512)) { if (_beginthread(( pThreadFunc )sendThread, 0, NULL)!=-1) @@ -241,6 +335,7 @@ void SkypeMsgCleanup(void) { MsgQ_Exit(&SkypeMsgs); LeaveCriticalSection(&ConnectMutex); DeleteCriticalSection(&ConnectMutex); + DeleteCriticalSection(&SendMutex); CloseHandle(SkypeMsgToSend); SkypeMsgToSend=NULL; MsgQ_Exit(&SkypeSendQueue); @@ -278,7 +373,7 @@ static int __sendMsg(char *szMsg) { return 0; } - if (UseSockets && ClientSocket==INVALID_SOCKET) return -1; + if (UseSockets && (ClientSocket==INVALID_SOCKET)) return -1; if (!MsgQ_Add(&SkypeSendQueue, szMsg) || !ReleaseSemaphore(SkypeMsgToSend, 1, NULL)) return -1; return 0; @@ -380,9 +475,12 @@ char *SkypeRcvTime(char *what, time_t st, DWORD maxwait) { msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); LOG(("=5)) { CheckDlgButton(hwndDlg, IDC_GROUPCHAT, db_get_b(NULL, SKYPE_PROTONAME, "UseGroupchat", 0) ? BST_CHECKED : BST_UNCHECKED); @@ -493,6 +493,7 @@ INT_PTR CALLBACK OptionsAdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, db_set_b (NULL, SKYPE_PROTONAME, "SuppressCallSummaryMessage", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SUPPRESSCALLSUMMARYMESSAGE))); db_set_b (NULL, SKYPE_PROTONAME, "NoSkype3Stats", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_NOSKYPE3STATS))); db_set_b (NULL, SKYPE_PROTONAME, "ShowFullname", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SHOWFULLNAME))); + db_set_b (NULL, SKYPE_PROTONAME, "NoAck", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_NOACK))); return TRUE; } break; @@ -750,21 +751,8 @@ int OnDetailsInit( WPARAM wParam, LPARAM lParam ) odp.hInstance = hInst; if ( hContact == NULL ) { - char szTitle[256]; - - if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 27) && !bIsImoproxy) - { - mir_snprintf( szTitle, SIZEOF( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Avatar" )); - - odp.pfnDlgProc = AvatarDlgProc; - odp.position = 1900000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETAVATAR); - odp.pszTitle = szTitle; - UserInfo_AddPage(wParam, &odp); - } - - mir_snprintf( szTitle, SIZEOF( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Details" )); + mir_snprintf(szTitle, SIZEOF( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Details" )); odp.pfnDlgProc = DetailsDlgProc; odp.position = 1900000000; diff --git a/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h index 8ce122990b..75a5de42ab 100644 --- a/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h +++ b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.h @@ -1,36 +1,11 @@ -/*** Skype API ***/ -//Messages -#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 -#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 -#define SKYPECONTROLAPI_ATTACH_REFUSED 2 -#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 -#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 - -// Errors -#define MISC_ERROR 1 -#define USER_NOT_FOUND 2 -#define USER_NOT_ONLINE 3 -#define USER_BLOCKED 4 -#define TYPE_UNSUPPORTED 5 -#define SENDER_NOT_FRIEND 6 -#define SENDER_NOT_AUTHORIZED 7 - - -/*** Debugging macros ***/ -#define OUTPUT(a) printf("* %s\n", a); -#define LOG(a, b) printf("- %s: %s\n", a, b); -#define LOGL(a, b) printf("- %s: %d\n", a, b); - /*** Program settings ***/ -#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available #define USE_AUTHENTICATION 0x01 // Program supports authentication -> Comment to disable! +#define USE_DATASLOTS 0x02 // Supports Commands >=3 /*** Commands ***/ #define AUTHENTICATE 0x01 #define CAPABILITIES 0x02 - -/*** Sockets ***/ -#pragma comment(lib, "ws2_32") - -/*** Prototypes ***/ -void WatchDogTimer(char *); \ No newline at end of file +#define MY_CAPABILITIES 0x03 +#define OPEN_SLOT 0x04 +#define DATA_SLOT 0x05 +#define CLOSE_SLOT 0x06 diff --git a/protocols/SkypeClassic/src/skypeproxy/skypeproxy_int.h b/protocols/SkypeClassic/src/skypeproxy/skypeproxy_int.h new file mode 100644 index 0000000000..f40b0b0e81 --- /dev/null +++ b/protocols/SkypeClassic/src/skypeproxy/skypeproxy_int.h @@ -0,0 +1,32 @@ +#include "skypeproxy.h" + +/*** Skype API ***/ +//Messages +#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 +#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 +#define SKYPECONTROLAPI_ATTACH_REFUSED 2 +#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 +#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 + +// Errors +#define MISC_ERROR 1 +#define USER_NOT_FOUND 2 +#define USER_NOT_ONLINE 3 +#define USER_BLOCKED 4 +#define TYPE_UNSUPPORTED 5 +#define SENDER_NOT_FRIEND 6 +#define SENDER_NOT_AUTHORIZED 7 + + +/*** Debugging macros ***/ +#define OUTPUT(a) printf("* %s\n", a); +#define LOG(x) printf x + +/*** Program settings ***/ +#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available + +/*** Sockets ***/ +#pragma comment(lib, "ws2_32") + +/*** Prototypes ***/ +void WatchDogTimer(void *); \ No newline at end of file diff --git a/protocols/SkypeClassic/src/skypesvc.cpp b/protocols/SkypeClassic/src/skypesvc.cpp index e5b1dc2c8e..1ca79ec62b 100644 --- a/protocols/SkypeClassic/src/skypesvc.cpp +++ b/protocols/SkypeClassic/src/skypesvc.cpp @@ -4,15 +4,15 @@ #include "skypeapi.h" #include "skypeopt.h" #include "contacts.h" -#include "m_toptoolbar.h" +#include "filexfer.h" // Exports SKYPE_SVCNAMES g_svcNames; //From skype.c +extern BOOL bHasFileXfer; extern char protocol, g_szProtoName[]; extern HINSTANCE hInst; -extern DWORD mirandaVersion; void CreateProtoService(const char* szService, MIRANDASERVICE svc) { @@ -27,7 +27,7 @@ void CreateServices(void) { CreateServiceName(ChatNew); CreateServiceName(SetAvatar); - CreateServiceName(SendFile); + CreateServiceName(SendGuiFile); CreateServiceName(HoldCall); CreateServiceName(AnswerCall); CreateServiceName(ImportHistory); @@ -44,7 +44,7 @@ void CreateServices(void) CreateServiceFunction(SKYPE_ADDUSER, SkypeAdduserDlg); CreateServiceFunction(SKYPE_IMPORTHISTORY, ImportHistory); CreateServiceFunction(SKYPE_ANSWERCALL, SkypeAnswerCall); - CreateServiceFunction(SKYPE_SENDFILE, SkypeSendFile); + CreateServiceFunction(SKYPE_SENDFILE, SkypeSendGuiFile); CreateServiceFunction(SKYPE_SETAVATAR, SkypeSetAvatar); CreateServiceFunction(SKYPE_BLOCKCONTACT, SkypeBlockContact); @@ -66,6 +66,12 @@ void CreateServices(void) CreateProtoService(PSR_AUTH, SkypeRecvAuth); CreateProtoService(PS_AUTHALLOW, SkypeAuthAllow); CreateProtoService(PS_AUTHDENY, SkypeAuthDeny); + CreateProtoService(PSR_FILE, SkypeRecvFile); + + CreateProtoService(PSS_FILEALLOWT, SkypeFileAllow); + CreateProtoService(PSS_FILEDENY, SkypeFileCancel); + CreateProtoService(PSS_FILECANCEL, SkypeFileCancel); + CreateProtoService(PSS_FILET, SkypeSendFile); CreateProtoService(PS_GETAVATARINFO, SkypeGetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, SkypeGetAvatarCaps); @@ -103,13 +109,14 @@ void HookEventsLoaded(void) INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM) { - int ret = 0; + INT_PTR ret = 0; switch (wParam) { case PFLAGNUM_1: ret = PF1_BASICSEARCH | PF1_IM | PF1_MODEMSG | PF1_SEARCHBYEMAIL; // | PF1_AUTHREQ; if (protocol>=5) ret |= PF1_ADDSEARCHRES; - break; + if (bHasFileXfer) ret |= PF1_FILE; + return ret; case PFLAGNUM_2: ret = PF2_ONLINE | PF2_SHORTAWAY | PF2_INVISIBLE | PF2_HEAVYDND; @@ -119,27 +126,21 @@ INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM) if (!db_get_b(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) ret |= PF2_LONGAWAY | PF2_FREECHAT; ret |= Proto_Status2Flag(db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE)); - break; + return ret; case PFLAGNUM_3: - ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE; - break; - + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE; case PFLAGNUM_4: - ret = PF4_FORCEAUTH | PF4_FORCEADDED | PF4_AVATARS | PF4_SUPPORTTYPING /* Not really, but libgaim compat. */; - if (mirandaVersion >= 0x070000) ret |= PF4_IMSENDUTF; - break; + return PF4_FORCEAUTH | PF4_FORCEADDED | PF4_AVATARS | PF4_SUPPORTTYPING /* Not really, but libgaim compat. */ | PF4_IMSENDUTF; case PFLAGNUM_5: - ret = Proto_Status2Flag(db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE)); - break; + return Proto_Status2Flag(db_get_dw(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE)); case PFLAG_UNIQUEIDTEXT: - ret = (INT_PTR)Translate("Skype ID"); - break; + return (INT_PTR)Translate("Skype ID"); case PFLAG_UNIQUEIDSETTING: - ret = (INT_PTR) SKYPE_NAME; - break; + return (INT_PTR) SKYPE_NAME; + default: + return 0; } - return ret; } INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam) diff --git a/protocols/SkypeClassic/src/version.h b/protocols/SkypeClassic/src/version.h index 24495eeb65..4238e086e1 100644 --- a/protocols/SkypeClassic/src/version.h +++ b/protocols/SkypeClassic/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 0 #define __RELEASE_NUM 0 -#define __BUILD_NUM 55 +#define __BUILD_NUM 56 #include -- cgit v1.2.3