diff options
author | dartraiden <wowemuh@gmail.com> | 2024-08-21 01:19:30 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2024-08-21 01:20:51 +0300 |
commit | aafdcb6859403d1786b9435322336e1a6e7cfcea (patch) | |
tree | 61f1ccdbea96ab9a69912b83692cfce6d70226db /protocols | |
parent | 3ebad9395945c3f4882054f442aa8211294355ed (diff) |
MRA: deprecate protocol
Diffstat (limited to 'protocols')
44 files changed, 10 insertions, 6457 deletions
diff --git a/protocols/CMakeLists.txt b/protocols/CMakeLists.txt index 0dfdbb12ec..a5aa3e58c7 100644 --- a/protocols/CMakeLists.txt +++ b/protocols/CMakeLists.txt @@ -3,7 +3,6 @@ add_subdirectory(Facebook)
#add_subdirectory(Gadu-Gadu)
#add_subdirectory(ICQCorp)
-add_subdirectory(ICQ-WIM)
add_subdirectory(IRCG)
add_subdirectory(JabberG)
#add_subdirectory(MinecraftDynmap)
diff --git a/protocols/Discord/proto_discord/src/resource.h b/protocols/Discord/proto_discord/src/resource.h index 1a283a2809..590b6e1ae6 100644 --- a/protocols/Discord/proto_discord/src/resource.h +++ b/protocols/Discord/proto_discord/src/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
-// Used by Proto_ICQ.rc
+// Used by Proto_Discord.rc
//
#define IDI_ICON1 105
#define IDI_ICON2 104
diff --git a/protocols/Dummy/src/main.cpp b/protocols/Dummy/src/main.cpp index 0dccbb7529..1374ed9944 100644 --- a/protocols/Dummy/src/main.cpp +++ b/protocols/Dummy/src/main.cpp @@ -142,3 +142,12 @@ struct CMPluginIcq : public ACCPROTOPLUGIN<CDummyProto> }
}
static g_pluginIcq;
+
+struct CMPluginMra : public ACCPROTOPLUGIN<CDummyProto>
+{
+ CMPluginMra() : ACCPROTOPLUGIN<CDummyProto>("MRA", pluginInfoEx)
+ {
+ SetUniqueId("aimId");
+ }
+}
+static g_pluginMra;
diff --git a/protocols/ICQ-WIM/CMakeLists.txt b/protocols/ICQ-WIM/CMakeLists.txt deleted file mode 100644 index 580e88e8c4..0000000000 --- a/protocols/ICQ-WIM/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -file(GLOB SOURCES "src/*.h" "src/*.cpp" "res/*.rc") -set(TARGET ICQ) -include(${CMAKE_SOURCE_DIR}/cmake/plugin.cmake) -target_link_libraries(${TARGET} libjson comctl32.lib ws2_32.lib) -add_subdirectory(proto_icq) diff --git a/protocols/ICQ-WIM/ICQ-WIM.vcxproj b/protocols/ICQ-WIM/ICQ-WIM.vcxproj deleted file mode 100644 index 226af870db..0000000000 --- a/protocols/ICQ-WIM/ICQ-WIM.vcxproj +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>ICQ</ProjectName> - <ProjectGuid>{EFB2355B-82B3-4759-B7D8-95F8E9506291}</ProjectGuid> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" /> - </ImportGroup> - <ItemGroup> - <ClCompile Include="src\avatars.cpp" /> - <ClCompile Include="src\file.cpp" /> - <ClCompile Include="src\groupchats.cpp" /> - <ClCompile Include="src\groups.cpp" /> - <ClCompile Include="src\http.cpp" /> - <ClCompile Include="src\ignore.cpp" /> - <ClCompile Include="src\main.cpp" /> - <ClCompile Include="src\menus.cpp" /> - <ClCompile Include="src\mra.cpp" /> - <ClCompile Include="src\options.cpp" /> - <ClCompile Include="src\poll.cpp" /> - <ClCompile Include="src\proto.cpp" /> - <ClCompile Include="src\server.cpp" /> - <ClCompile Include="src\stdafx.cxx"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="src\userinfo.cpp" /> - <ClCompile Include="src\utils.cpp" /> - <ClInclude Include="src\http.h" /> - <ClInclude Include="src\proto.h" /> - <ClInclude Include="src\resource.h" /> - <ClInclude Include="src\stdafx.h" /> - <ClInclude Include="src\version.h" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="res\resources.rc" /> - <ResourceCompile Include="res\version.rc" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters b/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters deleted file mode 100644 index c4f1468c1c..0000000000 --- a/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" /> - <ItemGroup> - <ClCompile Include="src\groupchats.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\http.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\ignore.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\main.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\options.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\poll.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\proto.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\server.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\stdafx.cxx"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\userinfo.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\utils.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\mra.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\groups.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\file.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\avatars.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="src\menus.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="src\http.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="src\proto.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="src\resource.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="src\stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="src\version.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="res\resources.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - <ResourceCompile Include="res\version.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/protocols/ICQ-WIM/proto_mra/CMakeLists.txt b/protocols/ICQ-WIM/proto_mra/CMakeLists.txt deleted file mode 100644 index f73e541f0b..0000000000 --- a/protocols/ICQ-WIM/proto_mra/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -set(TARGET Proto_MRA) -include(${CMAKE_SOURCE_DIR}/cmake/icons.cmake)
\ No newline at end of file diff --git a/protocols/ICQ-WIM/proto_mra/Proto_MRA.vcxproj b/protocols/ICQ-WIM/proto_mra/Proto_MRA.vcxproj deleted file mode 100644 index cf40e30f07..0000000000 --- a/protocols/ICQ-WIM/proto_mra/Proto_MRA.vcxproj +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectName>Proto_MRA</ProjectName> - <ProjectGuid>{38BF6F63-58E7-442D-A7E8-B4BD57D224E2}</ProjectGuid> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(ProjectDir)..\..\..\build\vc.common\icons.props" /> - </ImportGroup> - <ItemGroup> - <ClInclude Include="src\resource.h" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="res\Proto_MRA.rc" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/protocols/ICQ-WIM/proto_mra/Proto_MRA.vcxproj.filters b/protocols/ICQ-WIM/proto_mra/Proto_MRA.vcxproj.filters deleted file mode 100644 index c8734d39b6..0000000000 --- a/protocols/ICQ-WIM/proto_mra/Proto_MRA.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(ProjectDir)..\..\..\build\vc.common\common.filters" /> - <ItemGroup> - <ClInclude Include="src\resource.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="res\Proto_MRA.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/protocols/ICQ-WIM/proto_mra/res/Away.ico b/protocols/ICQ-WIM/proto_mra/res/Away.ico Binary files differdeleted file mode 100644 index 31a37341e4..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/Away.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/DND.ico b/protocols/ICQ-WIM/proto_mra/res/DND.ico Binary files differdeleted file mode 100644 index 1c7b1d4d37..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/DND.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/Invisible.ico b/protocols/ICQ-WIM/proto_mra/res/Invisible.ico Binary files differdeleted file mode 100644 index 10ea597f21..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/Invisible.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/NA.ico b/protocols/ICQ-WIM/proto_mra/res/NA.ico Binary files differdeleted file mode 100644 index e86658d5ae..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/NA.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/Occupied.ico b/protocols/ICQ-WIM/proto_mra/res/Occupied.ico Binary files differdeleted file mode 100644 index 2a4cdfadba..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/Occupied.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/Offline.ico b/protocols/ICQ-WIM/proto_mra/res/Offline.ico Binary files differdeleted file mode 100644 index ec4af077db..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/Offline.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/Online.ico b/protocols/ICQ-WIM/proto_mra/res/Online.ico Binary files differdeleted file mode 100644 index 41f825ad3b..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/Online.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/proto_mra/res/Proto_MRA.rc b/protocols/ICQ-WIM/proto_mra/res/Proto_MRA.rc deleted file mode 100644 index 86540dee25..0000000000 --- a/protocols/ICQ-WIM/proto_mra/res/Proto_MRA.rc +++ /dev/null @@ -1,76 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "..\src\resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian (Russia) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "..\\src\\resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON1 ICON "Offline.ico" -IDI_ICON2 ICON "Online.ico" -IDI_ICON3 ICON "Away.ico" -IDI_ICON4 ICON "Invisible.ico" -IDI_ICON5 ICON "NA.ico" -IDI_ICON6 ICON "DND.ico" -IDI_ICON7 ICON "Occupied.ico" - -#endif // Russian (Russia) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/protocols/ICQ-WIM/proto_mra/src/resource.h b/protocols/ICQ-WIM/proto_mra/src/resource.h deleted file mode 100644 index fcdca143d6..0000000000 --- a/protocols/ICQ-WIM/proto_mra/src/resource.h +++ /dev/null @@ -1,23 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Proto_MRA.rc -// -#define IDI_ICON1 105 -#define IDI_ICON2 104 -#define IDI_ICON3 128 -#define IDI_ICON4 130 -#define IDI_ICON5 131 -#define IDI_ICON6 158 -#define IDI_ICON7 159 -#define IDI_ICON8 129 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/protocols/ICQ-WIM/res/Forward.ico b/protocols/ICQ-WIM/res/Forward.ico Binary files differdeleted file mode 100644 index 0b6fa81f6c..0000000000 --- a/protocols/ICQ-WIM/res/Forward.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/res/Mail.ico b/protocols/ICQ-WIM/res/Mail.ico Binary files differdeleted file mode 100644 index 25bedbfbb2..0000000000 --- a/protocols/ICQ-WIM/res/Mail.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/res/MailNotify.ico b/protocols/ICQ-WIM/res/MailNotify.ico Binary files differdeleted file mode 100644 index 9e87d4bfcb..0000000000 --- a/protocols/ICQ-WIM/res/MailNotify.ico +++ /dev/null diff --git a/protocols/ICQ-WIM/res/resources.rc b/protocols/ICQ-WIM/res/resources.rc deleted file mode 100644 index 933d286bb3..0000000000 --- a/protocols/ICQ-WIM/res/resources.rc +++ /dev/null @@ -1,345 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "..\src\resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian (Russia) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_EDITGROUPS DIALOGEX 0, 0, 262, 255 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Edit server groups" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,205,234,50,14 - CONTROL "",IDC_GROUPS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_AUTOARRANGE | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,248,222 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_EDITGROUPS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 255 - TOPMARGIN, 7 - BOTTOMMARGIN, 248 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// AFX_DIALOG_LAYOUT -// - -IDD_EDITGROUPS AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 0, 0, - 0, 0, 0, 100 -END - -#endif // Russian (Russia) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPTIONS_ACCMGR DIALOGEX 0, 0, 189, 51 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "E-mail:",IDC_UIN_LABEL,0,2,53,8 - EDITTEXT IDC_UIN,54,0,131,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,0,18,53,8 - EDITTEXT IDC_PASSWORD,54,17,131,12,ES_PASSWORD | ES_AUTOHSCROLL - PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,42,34,142,14 -END - -IDD_OPTIONS_FULL DIALOGEX 0, 0, 310, 123 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "MRA",IDC_STATIC,1,0,305,62 - RTEXT "E-mail:",IDC_UIN_LABEL,10,14,79,8 - EDITTEXT IDC_UIN,98,12,106,12,ES_AUTOHSCROLL - RTEXT "Password:",IDC_STATIC,10,30,79,8 - EDITTEXT IDC_PASSWORD,98,29,106,12,ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Do not open chat windows on creation",IDC_HIDECHATS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,47,285,10 - CONTROL "Use tray icon notifications",IDC_USETRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,73,291,10 - CONTROL "Launch mailbox in a browser on click",IDC_LAUNCH_MAILBOX, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,85,281,10 - PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,165,104,142,14 - GROUPBOX "Notifications",IDC_STATIC,1,62,306,38 -END - -IDD_OPTIONS_ADV DIALOGEX 0, 0, 310, 86 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "If a contact goes Offline, set this status instead and cache it for given timeout in seconds (0 - disabled)",IDC_STATIC,12,16,204,23 - EDITTEXT IDC_DIFF1,221,13,54,12,ES_AUTOHSCROLL - CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,275,12,11,14 - COMBOBOX IDC_STATUS1,221,28,81,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "After that, set this status to a contact and move it offline after specified timeout in seconds (0 - disabled)",IDC_STATIC,12,49,204,23 - EDITTEXT IDC_DIFF2,221,46,54,12,ES_AUTOHSCROLL - CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,275,45,11,14 - COMBOBOX IDC_STATUS2,221,61,81,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -END - -IDD_GROUPCHAT_INVITE DIALOGEX 0, 0, 215, 263 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Send group chat invitation" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_CLIST,"CListControl",WS_TABSTOP | 0x1,7,7,201,231,WS_EX_CLIENTEDGE - DEFPUSHBUTTON "&Invite",IDOK,104,243,50,14 - PUSHBUTTON "Cancel",IDCANCEL,158,243,50,14 -END - -IDD_REGISTER DIALOGEX 0, 0, 316, 111 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_APPWINDOW -CAPTION "Account registration" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,205,90,50,14 - PUSHBUTTON "Cancel",IDCANCEL,259,90,50,14 - LTEXT "Enter full phone number",IDC_STATIC,7,7,302,14 - EDITTEXT IDC_PHONE,7,18,302,14,ES_AUTOHSCROLL - PUSHBUTTON "Send me registration code via SMS",IDC_SENDSMS,49,37,221,14,BS_CENTER | WS_DISABLED - LTEXT "Enter registration code",IDC_STATIC,7,58,302,8 - EDITTEXT IDC_CODE,7,70,302,14,ES_AUTOHSCROLL | WS_DISABLED -END - -IDD_INFO_ICQ DIALOGEX 0, 0, 222, 132 -STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "UIN:",IDC_STATIC,5,7,63,8 - EDITTEXT IDC_UIN,74,6,139,10,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Nick:",IDC_STATIC,5,21,63,8 - EDITTEXT IDC_NICK,74,20,139,10,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Last seen:",IDC_STATIC,5,93,63,22 - EDITTEXT IDC_LASTSEEN,74,92,139,10,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Online since:",IDC_STATIC,5,79,63,8 - EDITTEXT IDC_ONLINESINCE,74,78,139,10,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Phone number:",IDC_STATIC,5,65,63,8 - EDITTEXT IDC_PHONE,74,64,139,10,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "First name:",IDC_STATIC,5,36,63,8 - EDITTEXT IDC_FIRST_NAME,74,35,139,10,ES_AUTOHSCROLL | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Last name:",IDC_STATIC,5,50,63,8 - EDITTEXT IDC_LAST_NAME,74,50,139,10,ES_AUTOHSCROLL | NOT WS_BORDER | NOT WS_TABSTOP -END - -IDD_ABOUT DIALOGEX 0, 0, 222, 132 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "About:",IDC_STATIC,5,5,212,8 - EDITTEXT IDC_ABOUT,5,15,212,112,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL -END - -IDD_LOGINPW DIALOGEX 0, 0, 157, 70 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Enter MRA password" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Enter a password:",IDC_STATIC,7,7,142,8 - EDITTEXT IDC_PASSWORD,7,16,142,14,ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Remember this session password",IDC_SAVEPASS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,38,142,10 - DEFPUSHBUTTON "OK",IDOK,47,53,50,14 - PUSHBUTTON "Cancel",IDCANCEL,102,53,50,14 -END - -IDD_FORWARD DIALOGEX 0, 0, 215, 267 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Forward message" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_CLIST,"CListControl",WS_TABSTOP | 0x1,8,4,201,239,WS_EX_CLIENTEDGE - DEFPUSHBUTTON "Forward",IDOK,104,248,50,14 - PUSHBUTTON "Cancel",IDCANCEL,158,248,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_OPTIONS_ACCMGR, DIALOG - BEGIN - RIGHTMARGIN, 186 - END - - IDD_OPTIONS_FULL, DIALOG - BEGIN - BOTTOMMARGIN, 118 - END - - IDD_OPTIONS_ADV, DIALOG - BEGIN - END - - IDD_GROUPCHAT_INVITE, DIALOG - BEGIN - END - - IDD_REGISTER, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 309 - TOPMARGIN, 7 - BOTTOMMARGIN, 104 - END - - IDD_INFO_ICQ, DIALOG - BEGIN - END - - IDD_LOGINPW, DIALOG - BEGIN - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// AFX_DIALOG_LAYOUT -// - -IDD_OPTIONS_FULL AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_OPTIONS_ACCMGR AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_GROUPCHAT_INVITE AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_REGISTER AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_INFO_ICQ AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_OPTIONS_ADV AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_LOGINPW AFX_DIALOG_LAYOUT -BEGIN - 0 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_INBOX ICON "Mail.ico" - -IDI_MAIL_NOTIFY ICON "MailNotify.ico" - -IDI_FORWARD ICON "Forward.ico" - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "..\\src\\resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/protocols/ICQ-WIM/res/version.rc b/protocols/ICQ-WIM/res/version.rc deleted file mode 100644 index 5a5ddd63ed..0000000000 --- a/protocols/ICQ-WIM/res/version.rc +++ /dev/null @@ -1,9 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - -#include "..\src\version.h" - -#include "..\..\build\Version.rc" diff --git a/protocols/ICQ-WIM/src/avatars.cpp b/protocols/ICQ-WIM/src/avatars.cpp deleted file mode 100644 index a8df1a879b..0000000000 --- a/protocols/ICQ-WIM/src/avatars.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) - -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 version 2 -of the License. - -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, see <http://www.gnu.org/licenses/>. -*/ - -#include "stdafx.h" - -///////////////////////////////////////////////////////////////////////////////////////// -// Avatars - -void CIcqProto::GetAvatarFileName(MCONTACT hContact, wchar_t *pszDest, size_t cbLen) -{ - CMStringW wszPath(GetAvatarPath()); - wszPath += '\\'; - - CMStringW wszFileName(getMStringW(hContact, "IconId")); - const wchar_t *szFileType = ProtoGetAvatarExtension(getByte(hContact, "AvatarType", PA_FORMAT_PNG)); - wszPath.AppendFormat(L"%s%s", wszFileName.c_str(), szFileType); - - wcsncpy_s(pszDest, cbLen, wszPath, _TRUNCATE); -} - -INT_PTR __cdecl CIcqProto::GetAvatar(WPARAM wParam, LPARAM lParam) -{ - wchar_t *buf = (wchar_t *)wParam; - int size = (int)lParam; - if (buf == nullptr || size <= 0) - return -1; - - GetAvatarFileName(0, buf, size); - return 0; -} - -INT_PTR __cdecl CIcqProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) { - case AF_MAXSIZE: - ((POINT *)lParam)->x = -1; - ((POINT *)lParam)->y = -1; - return 0; - - case AF_FORMATSUPPORTED: // nobody - return 1; - - case AF_DELAYAFTERFAIL: - return 10 * 60 * 1000; - - case AF_ENABLED: - case AF_FETCHIFPROTONOTVISIBLE: - case AF_FETCHIFCONTACTOFFLINE: - return 1; - } - return 0; -} - -INT_PTR __cdecl CIcqProto::GetAvatarInfo(WPARAM, LPARAM lParam) -{ - PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION *)lParam; - - ptrW szIconId(getWStringA(pai->hContact, "IconId")); - if (szIconId == nullptr) { - debugLogA("No avatar"); - return GAIR_NOAVATAR; - } - - GetAvatarFileName(pai->hContact, pai->filename, _countof(pai->filename)); - pai->format = getByte(pai->hContact, "AvatarType", 0); - - if (::_waccess(pai->filename, 0) == 0) - return GAIR_SUCCESS; - - debugLogA("No avatar"); - return GAIR_NOAVATAR; -} - -INT_PTR __cdecl CIcqProto::SetAvatar(WPARAM, LPARAM lParam) -{ - wchar_t *pwszFileName = (wchar_t *)lParam; - - wchar_t wszOldName[MAX_PATH]; - GetAvatarFileName(0, wszOldName, _countof(wszOldName)); - _wremove(wszOldName); - - auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_POST, "/expressions/upload"); - pReq->m_szUrl.AppendFormat("?f=json&aimsid=%s&r=%s&type=largeBuddyIcon", mir_urlEncode(m_aimsid.c_str()).c_str(), pReq->m_reqId); - - if (pwszFileName == nullptr) - delSetting("AvatarHash"); - else { - int fileId = _wopen(pwszFileName, _O_RDONLY | _O_BINARY, _S_IREAD); - if (fileId < 0) { - delete pReq; - return 1; - } - - unsigned dwSize = (unsigned)_filelengthi64(fileId); - pReq->m_szParam.Truncate(dwSize); - _read(fileId, pReq->m_szParam.GetBuffer(), dwSize); - _close(fileId); - - int iAvatarType = ProtoGetBufferFormat(pReq->m_szParam); - if (iAvatarType == PA_FORMAT_UNKNOWN) { - delete pReq; - return 3; - } - - pReq->AddHeader("Content-Type", ProtoGetAvatarMimeType(iAvatarType)); - } - Push(pReq); - - return 0; // TODO -} diff --git a/protocols/ICQ-WIM/src/file.cpp b/protocols/ICQ-WIM/src/file.cpp deleted file mode 100644 index 8322a833c6..0000000000 --- a/protocols/ICQ-WIM/src/file.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) - -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 version 2 -of the License. - -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, see <http://www.gnu.org/licenses/>. -*/ - -#include "stdafx.h" - -// create an object for sending -IcqFileTransfer::IcqFileTransfer(MCONTACT hContact, const wchar_t *pwszFileName) : - m_wszFileName(pwszFileName) -{ - pfts.flags = PFTS_UNICODE | PFTS_SENDING; - pfts.hContact = hContact; - pfts.szCurrentFile.w = m_wszFileName.GetBuffer(); - - const wchar_t *p = wcsrchr(pfts.szCurrentFile.w, '\\'); - if (pwszFileName != nullptr) - p++; - else - p = pfts.szCurrentFile.w; - m_wszShortName = p; -} - -IcqFileTransfer::~IcqFileTransfer() -{ - if (m_fileId >= 0) - _close(m_fileId); -} - -void IcqFileTransfer::FillHeaders(AsyncHttpRequest *pReq) -{ - pReq->AddHeader("Content-Type", "application/octet-stream"); - pReq->AddHeader("Content-Disposition", CMStringA(FORMAT, "attachment; filename=\"%s\"", T2Utf(m_wszShortName).get())); - - uint32_t dwPortion = pfts.currentFileSize - pfts.currentFileProgress; - if (dwPortion > 1000000) - dwPortion = 1000000; - - pReq->AddHeader("Content-Range", CMStringA(FORMAT, "bytes %lld-%lld/%lld", pfts.currentFileProgress, pfts.currentFileProgress + dwPortion - 1, pfts.currentFileSize)); - pReq->AddHeader("Content-Length", CMStringA(FORMAT, "%d", dwPortion)); - - pReq->m_szParam.Truncate(dwPortion); - _lseek(m_fileId, pfts.currentFileProgress, SEEK_SET); - _read(m_fileId, pReq->m_szParam.GetBuffer(), dwPortion); - - pfts.currentFileProgress += dwPortion; - pfts.totalProgress += dwPortion; -} diff --git a/protocols/ICQ-WIM/src/groupchats.cpp b/protocols/ICQ-WIM/src/groupchats.cpp deleted file mode 100644 index 17cab08731..0000000000 --- a/protocols/ICQ-WIM/src/groupchats.cpp +++ /dev/null @@ -1,329 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-SESSION_INFO* CIcqProto::GcCreate(const wchar_t *pwszId, const wchar_t *pwszNick)
-{
- auto *si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, pwszId, pwszNick);
- if (si == nullptr)
- return nullptr;
-
- if (si->pStatuses == 0) {
- Chat_AddGroup(si, TranslateT("admin"));
- Chat_AddGroup(si, TranslateT("member"));
- }
-
- Chat_Control(si, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE);
- Chat_Control(si, SESSION_ONLINE);
-
- // #3420 ICQ server will place our group chat into its own group
- Clist_SetGroup(si->hContact, nullptr);
-
- if (si->ptszTopic) {
- GCEVENT gce = { si, GC_EVENT_TOPIC };
- gce.time = ::time(0);
- gce.pszText.w = si->ptszTopic; si->ptszTopic = 0;
- Chat_Event(&gce);
-
- mir_free((void*)gce.pszText.w);
- }
-
- return si;
-}
-
-INT_PTR CIcqProto::SvcLeaveChat(WPARAM hContact, LPARAM)
-{
- CMStringW wszId(GetUserId(hContact));
- if (auto *si = Chat_Find(wszId, m_szModuleName))
- LeaveDestroyChat(si);
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGetChatInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- RobustReply root(pReply);
- if (root.error() != 20000)
- return;
-
- SESSION_INFO *si = (SESSION_INFO *)pReq->pUserInfo;
-
- const JSONNode &results = root.results();
- for (auto &it : results["members"]) {
- CMStringW friendly = it["friendly"].as_mstring();
- CMStringW role = it["role"].as_mstring();
- CMStringW sn = it["sn"].as_mstring();
-
- GCEVENT gce = { si, GC_EVENT_JOIN };
- gce.dwFlags = GCEF_SILENT;
- gce.pszNick.w = friendly;
- gce.pszUID.w = sn;
- gce.time = ::time(0);
- gce.bIsMe = sn == m_szOwnId;
- gce.pszStatus.w = TranslateW(role);
- Chat_Event(&gce);
- }
-
- CMStringW wszAbout = results["about"].as_mstring(), wszTopic;
- CMStringW wszRules = results["rules"].as_mstring();
- if (!wszAbout.IsEmpty())
- wszTopic.AppendFormat(L"%s: %s", TranslateT("About"), wszAbout.c_str());
- if (!wszRules.IsEmpty()) {
- if (!wszTopic.IsEmpty())
- wszTopic.Append(L"\r\n");
- wszTopic.AppendFormat(L"%s: %s", TranslateT("Rules"), wszRules.c_str());
- }
- if (!wszTopic.IsEmpty()) {
- GCEVENT gce = { si, GC_EVENT_TOPIC };
- gce.time = ::time(0);
- gce.pszText.w = wszTopic;
- Chat_Event(&gce);
- }
-
- setId(si->hContact, "InfoVersion", _wtoi64(results["infoVersion"].as_mstring()));
- setId(si->hContact, "MembersVersion", _wtoi64(results["membersVersion"].as_mstring()));
-}
-
-void CIcqProto::RetrieveChatInfo(MCONTACT hContact)
-{
- CMStringW wszChatID(GetUserId(hContact));
- if (auto *si = Chat_Find(wszChatID, m_szModuleName)) {
- auto *pReq = new AsyncRapiRequest(this, "getChatInfo", &CIcqProto::OnGetChatInfo);
- pReq->params << WCHAR_PARAM("sn", wszChatID) << INT_PARAM("memberLimit", 100) << CHAR_PARAM("aimSid", m_aimsid);
- pReq->pUserInfo = si;
- Push(pReq);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Invitation dialog
-
-class CGroupchatInviteDlg : public CIcqDlgBase
-{
- CCtrlClc m_clc;
- SESSION_INFO *m_si;
-
- void FilterList(CCtrlClc*)
- {
- for (auto &hContact : Contacts()) {
- char *proto = Proto_GetBaseAccountName(hContact);
- if (mir_strcmp(proto, m_proto->m_szModuleName) || m_proto->isChatRoom(hContact))
- if (HANDLE hItem = m_clc.FindContact(hContact))
- m_clc.DeleteItem(hItem);
- }
- }
-
- void ResetListOptions(CCtrlClc*)
- {
- m_clc.SetHideEmptyGroups(1);
- m_clc.SetHideOfflineRoot(1);
- }
-
-public:
- CGroupchatInviteDlg(CIcqProto *ppro, SESSION_INFO *si) :
- CIcqDlgBase(ppro, IDD_GROUPCHAT_INVITE),
- m_si(si),
- m_clc(this, IDC_CLIST)
- {
- m_clc.OnNewContact =
- m_clc.OnListRebuilt = Callback(this, &CGroupchatInviteDlg::FilterList);
- m_clc.OnOptionsChanged = Callback(this, &CGroupchatInviteDlg::ResetListOptions);
- }
-
- bool OnInitDialog() override
- {
- SetWindowLongPtr(m_clc.GetHwnd(), GWL_STYLE,
- GetWindowLongPtr(m_clc.GetHwnd(), GWL_STYLE) | CLS_SHOWHIDDEN | CLS_HIDEOFFLINE | CLS_CHECKBOXES | CLS_HIDEEMPTYGROUPS | CLS_USEGROUPS | CLS_GREYALTERNATE | CLS_GROUPCHECKBOXES);
- m_clc.SendMsg(CLM_SETEXSTYLE, CLS_EX_DISABLEDRAGDROP | CLS_EX_TRACKSELECT, 0);
-
- ResetListOptions(&m_clc);
- FilterList(&m_clc);
- return true;
- }
-
- bool OnApply() override
- {
- CMStringW szMembers;
- for (auto &hContact : m_proto->AccContacts()) {
- if (m_proto->isChatRoom(hContact))
- continue;
-
- if (HANDLE hItem = m_clc.FindContact(hContact)) {
- if (m_clc.GetCheck(hItem)) {
- if (!szMembers.IsEmpty())
- szMembers.AppendChar(',');
- szMembers.Append(m_proto->GetUserId(hContact));
- }
- }
- }
-
- m_proto->Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/mchat/AddChat")
- << AIMSID(m_proto) << WCHAR_PARAM("chat_id", m_si->ptszID) << WCHAR_PARAM("members", szMembers));
- return true;
- }
-};
-
-void CIcqProto::InviteUserToChat(SESSION_INFO *si)
-{
- CGroupchatInviteDlg dlg(this, si);
- if (si->pDlg)
- dlg.SetParent(((CDlgBase*)si->pDlg)->GetHwnd());
- dlg.DoModal();
-}
-
-void CIcqProto::OnLeaveChat(MHttpResponse*, AsyncHttpRequest *pReq)
-{
- db_delete_contact(INT_PTR(pReq->pUserInfo));
-}
-
-void CIcqProto::LeaveDestroyChat(SESSION_INFO *si)
-{
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/hideChat", &CIcqProto::OnLeaveChat)
- << AIMSID(this) << WCHAR_PARAM("buddy", si->ptszID) << INT64_PARAM("lastMsgId", getId(si->hContact, DB_KEY_LASTMSGID));
- pReq->pUserInfo = (void *)si->hContact;
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Group chats
-
-static gc_item sttLogListItems[] =
-{
- { LPGENW("&Invite a user"), IDM_INVITE, MENU_ITEM },
- { nullptr, 0, MENU_SEPARATOR },
- { LPGENW("&Leave/destroy chat"), IDM_LEAVE, MENU_ITEM }
-};
-
-int CIcqProto::GcMenuHook(WPARAM, LPARAM lParam)
-{
- GCMENUITEMS *gcmi = (GCMENUITEMS*)lParam;
- if (gcmi == nullptr)
- return 0;
-
- if (mir_strcmpi(gcmi->pszModule, m_szModuleName))
- return 0;
-
- SESSION_INFO *si = Chat_Find(gcmi->pszID, gcmi->pszModule);
- if (si == nullptr)
- return 0;
-
- if (gcmi->Type == MENU_ON_LOG)
- Chat_AddMenuItems(gcmi->hMenu, _countof(sttLogListItems), sttLogListItems, &g_plugin);
-
- return 0;
-}
-
-int CIcqProto::GcEventHook(WPARAM, LPARAM lParam)
-{
- GCHOOK *gch = (GCHOOK*)lParam;
- if (gch == nullptr)
- return 0;
-
- if (mir_strcmpi(gch->si->pszModule, m_szModuleName))
- return 0;
-
- SESSION_INFO *si = gch->si;
-
- switch (gch->iType) {
- case GC_USER_MESSAGE:
- rtrimw(gch->ptszText);
- if (!mir_wstrlen(gch->ptszText))
- break;
-
- if (m_bOnline) {
- wchar_t *wszText = NEWWSTR_ALLOCA(gch->ptszText);
- Chat_UnescapeTags(wszText);
- SendMsg(si->hContact, 0, T2Utf(wszText));
- }
- break;
-
- case GC_USER_PRIVMESS:
- GcSendPrivateMessage(gch);
- break;
-
- case GC_USER_LOGMENU:
- GcProcessLogMenu(si, gch->dwData);
- break;
- }
-
- return 1;
-}
-
-void CIcqProto::GcProcessLogMenu(SESSION_INFO *si, int iChoice)
-{
- switch (iChoice) {
- case IDM_INVITE:
- InviteUserToChat(si);
- break;
-
- case IDM_LEAVE:
- LeaveDestroyChat(si);
- break;
- }
-}
-
-void CIcqProto::GcSendPrivateMessage(GCHOOK *gch)
-{
- MCONTACT hContact;
- auto *pUser = FindUser(gch->ptszUID);
- if (pUser == nullptr) {
- hContact = CreateContact(gch->ptszUID, true);
- setWString(hContact, "Nick", gch->ptszNick);
- Contact::Hide(hContact);
- db_set_dw(hContact, "Ignore", "Mask1", 0);
- }
- else hContact = pUser->m_hContact;
-
- CallService(MS_MSG_SENDMESSAGE, hContact, 0);
-}
-
-void CIcqProto::ProcessGroupChat(const JSONNode &ev)
-{
- for (auto &it : ev["mchats"]) {
- CMStringW wszId(it["sender"].as_mstring());
- auto *si = Chat_Find(wszId, m_szModuleName);
- if (si == nullptr)
- continue;
-
- CMStringW method(it["method"].as_mstring());
- GCEVENT gce = { si, (method == "add_members") ? GC_EVENT_JOIN : GC_EVENT_PART };
-
- int iStart = 0;
- CMStringW members(it["members"].as_mstring());
- while (true) {
- CMStringW member = members.Tokenize(L",", iStart);
- if (member.IsEmpty())
- break;
-
- auto *pUser = FindUser(member);
- if (pUser == nullptr)
- continue;
-
- gce.pszNick.w = Clist_GetContactDisplayName(pUser->m_hContact);
- gce.pszUID.w = member;
- gce.time = ::time(0);
- gce.bIsMe = member == m_szOwnId;
- Chat_Event(&gce);
- }
- }
-}
diff --git a/protocols/ICQ-WIM/src/groups.cpp b/protocols/ICQ-WIM/src/groups.cpp deleted file mode 100644 index c90f2594b7..0000000000 --- a/protocols/ICQ-WIM/src/groups.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) - -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 version 2 -of the License. - -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, see <http://www.gnu.org/licenses/>. -*/ - -#include "stdafx.h" - -INT_PTR CIcqProto::UploadGroups(WPARAM, LPARAM) -{ - for (auto &it : AccContacts()) { - if (isChatRoom(it)) - continue; - - ptrW wszIcqGroup(getWStringA(it, "IcqGroup")); - if (wszIcqGroup == nullptr) - continue; - - ptrW wszMirGroup(Clist_GetGroup(it)); - if (!wszMirGroup) - wszMirGroup = mir_wstrdup(L"General"); - if (mir_wstrcmp(wszIcqGroup, wszMirGroup)) - MoveContactToGroup(it, wszIcqGroup, wszMirGroup); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -class CGroupEditDlg : public CIcqDlgBase -{ - CCtrlListView groups; - -public: - - static CGroupEditDlg *pDlg; - - CGroupEditDlg(CIcqProto *ppro) : - CIcqDlgBase(ppro, IDD_EDITGROUPS), - groups(this, IDC_GROUPS) - { - groups.OnBuildMenu = Callback(this, &CGroupEditDlg::onMenu); - } - - void RefreshGroups() - { - groups.DeleteAllItems(); - - for (auto &it : m_proto->m_arGroups) - groups.AddItem(it->wszName, 0, (LPARAM)it); - } - - bool OnInitDialog() override - { - pDlg = this; - groups.AddColumn(0, TranslateT("Name"), 300); - RefreshGroups(); - return true; - } - - void OnDestroy() override - { - pDlg = nullptr; - } - - void onMenu(void *) - { - int cur = groups.GetSelectionMark(); - if (cur == -1) - return; - - IcqGroup *pGroup = (IcqGroup *)groups.GetItemData(cur); - - HMENU hMenu = CreatePopupMenu(); - AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename")); - AppendMenu(hMenu, MF_STRING, 2, TranslateT("Delete")); - - POINT pt; - GetCursorPos(&pt); - int cmd = TrackPopupMenu(hMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr); - DestroyMenu(hMenu); - - if (cmd == 1) { // rename - ENTER_STRING es = {}; - es.szModuleName = m_proto->m_szModuleName; - es.caption = TranslateT("Enter new group name"); - if (!EnterString(&es)) - return; - - m_proto->Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/renameGroup") - << AIMSID(m_proto) << WCHAR_PARAM("oldGroup", pGroup->wszSrvName) << GROUP_PARAM("newGroup", es.ptszResult)); - - mir_free(es.ptszResult); - } - else if (cmd == 2) { // delete - m_proto->Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/removeGroup") - << AIMSID(m_proto) << WCHAR_PARAM("group", pGroup->wszSrvName)); - } - } -}; - -CGroupEditDlg *CGroupEditDlg::pDlg = nullptr; - -INT_PTR CIcqProto::EditGroups(WPARAM, LPARAM) -{ - (new CGroupEditDlg(this))->Show(); - return 0; -} - -void RefreshGroups(void) -{ - if (CGroupEditDlg::pDlg != nullptr) - CGroupEditDlg::pDlg->RefreshGroups(); -} diff --git a/protocols/ICQ-WIM/src/http.cpp b/protocols/ICQ-WIM/src/http.cpp deleted file mode 100644 index f6035bbc97..0000000000 --- a/protocols/ICQ-WIM/src/http.cpp +++ /dev/null @@ -1,364 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-void CIcqProto::DropQueue()
-{
- mir_cslock lck(m_csHttpQueue);
-
- while (m_arHttpQueue.getCount()) {
- auto *pReq = m_arHttpQueue[0];
- m_arHttpQueue.remove(0);
- delete pReq;
- }
-}
-
-bool CIcqProto::IsQueueEmpty()
-{
- mir_cslock lck(m_csHttpQueue);
- return m_arHttpQueue.getCount() == 0;
-}
-
-void __cdecl CIcqProto::ServerThread(void*)
-{
- memset(&m_ConnPool, 0, sizeof(m_ConnPool));
- m_bTerminated = false;
-
- debugLogA("CIcqProto::WorkerThread: %s", "entering");
-
- while (true) {
- WaitForSingleObject(m_evRequestsQueue, 1000);
- if (m_bTerminated)
- break;
-
- while (true) {
- bool bNeedSleep = false;
- AsyncHttpRequest *pReq;
- {
- mir_cslock lck(m_csHttpQueue);
- if (m_arHttpQueue.getCount() == 0)
- break;
-
- pReq = m_arHttpQueue[0];
- m_arHttpQueue.remove(0);
- bNeedSleep = (m_arHttpQueue.getCount() > 1);
- }
- if (m_bTerminated)
- break;
-
- ExecuteRequest(pReq);
- if (bNeedSleep)
- Sleep(200);
- }
-
- int ts = time(0);
- for (auto &it : m_ConnPool) {
- int idx = int(&it - m_ConnPool);
- if (idx == CONN_FETCH)
- continue;
-
- if (it.s && it.lastTs + it.timeout < ts) {
- debugLogA("Socket #1 (%p) expired", idx, it.s);
- Netlib_CloseHandle(it.s);
- it.s = nullptr;
- it.lastTs = 0;
- }
- }
- }
-
- m_hWorkerThread = nullptr;
- for (auto &it : m_ConnPool) {
- if (it.s)
- Netlib_CloseHandle(it.s);
- it.s = nullptr;
- it.lastTs = it.timeout = 0;
- }
-
- debugLogA("CIcqProto::WorkerThread: %s", "leaving");
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-AsyncRapiRequest::AsyncRapiRequest(CIcqProto *ppro, const char *pszMethod, MTHttpRequestHandler pFunc, int mode) :
- AsyncHttpRequest(CONN_RAPI, REQUEST_POST, (mode == -1) ? ICQ_ROBUST_SERVER : ICQ_ROBUST_SERVER_NEW, pFunc)
-{
- params.set_name("params");
-
- if (mode == -1)
- mode = ppro->getByte(DB_KEY_PHONEREG);
-
- if (mode) {
- m_szUrl.AppendChar('/');
- m_szUrl.Append(pszMethod);
-
- AddHeader("Content-Type", "application/json");
- request << CHAR_PARAM("aimsid", ppro->m_aimsid);
- }
- else request << CHAR_PARAM("method", pszMethod);
-}
-
-void AsyncRapiRequest::OnPush()
-{
- request << CHAR_PARAM("reqId", m_reqId) << params;
-
- m_szParam = ptrW(json_write(&request));
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-AsyncHttpRequest::AsyncHttpRequest(IcqConnection conn, int iType, const char *szUrl, MTHttpRequestHandler pFunc) :
- m_conn(conn)
-{
- flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_DUMPASTEXT;
- requestType = iType;
- m_szUrl = szUrl;
- m_pFunc = pFunc;
- timeout = 10000;
-
- if (conn == CONN_OLD) {
- m_conn = CONN_MAIN;
- m_szUrl.Insert(0, "https://u.icq.net/wim/v17");
- }
- else if (*szUrl == '/')
- m_szUrl.Insert(0, "https://u.icq.net/wim");
-
- strncpy_s(m_reqId, Utils_GenerateUUID(), _TRUNCATE);
-
- if (iType == REQUEST_POST)
- AddHeader("Content-Type", "application/x-www-form-urlencoded");
-}
-
-void AsyncHttpRequest::ReplaceJsonParam(const JSONNode &n)
-{
- auto *szNodeName = n.name();
-
- JSONNode root = JSONNode::parse(m_szParam);
- JSONNode& old = root.at(szNodeName);
- if (old)
- old = n;
- else
- root.push_back(n);
- m_szParam = root.write().c_str();
-}
-
-bool CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
-{
- // replace credentials inside JSON body for pure RAPI requests
- if (pReq->m_conn == CONN_RAPI && !mir_strcmp(pReq->m_szUrl, ICQ_ROBUST_SERVER) && !getByte(DB_KEY_PHONEREG)) {
- CMStringA szAgent(FORMAT, "%S Mail.ru Windows ICQ (version 10.0.1999)", (wchar_t*)m_szOwnId);
- pReq->AddHeader("User-Agent", szAgent);
- pReq->AddHeader("Content-Type", "application/json");
-
- if (m_szRToken.IsEmpty()) {
- if (!RefreshRobustToken(pReq)) {
- delete pReq;
- return false;
- }
- }
-
- if (m_iRClientId)
- pReq->ReplaceJsonParam(JSONNode("clientId", m_iRClientId));
- pReq->ReplaceJsonParam(JSONNode("authToken", m_szRToken));
- }
-
- debugLogA("Executing request %s:\n%s", pReq->m_reqId, pReq->m_szUrl.c_str());
-
- if (pReq->m_conn != CONN_NONE) {
- pReq->flags |= NLHRF_PERSISTENT;
- pReq->nlc = m_ConnPool[pReq->m_conn].s;
- m_ConnPool[pReq->m_conn].lastTs = time(0);
- }
-
- bool bRet;
- NLHR_PTR reply(Netlib_HttpTransaction(m_hNetlibUser, pReq));
- if (reply != nullptr) {
- if (pReq->m_conn != CONN_NONE) {
- auto &conn = m_ConnPool[pReq->m_conn];
- conn.s = reply->nlc;
- conn.timeout = 0;
- if (auto *pszHdr = reply->FindHeader("Keep-Alive")) {
- int timeout;
- if (1 == sscanf(pszHdr, "timeout=%d", &timeout))
- conn.timeout = timeout;
- }
- }
-
- if (pReq->m_conn == CONN_RAPI && reply->body.Find("\"code\":") != -1) {
- RobustReply r(reply);
- if (r.error() == 40201 || r.error() == 40200) { // robust token expired
- m_szRToken.Empty();
-
- // if token refresh succeeded, replace it in the query and push request back
- if (!RefreshRobustToken(pReq)) {
- delete pReq;
- return false;
- }
-
- Push(pReq);
- return true;
- }
- }
-
- if (pReq->m_pFunc != nullptr)
- (this->*(pReq->m_pFunc))(reply, pReq);
-
- bRet = true;
- }
- else {
- debugLogA("Request %s failed", pReq->m_reqId);
-
- if (IsStatusConnecting(m_iStatus))
- ConnectionFailed(LOGINERR_NONETWORK);
-
- if (pReq->m_conn != CONN_NONE)
- m_ConnPool[pReq->m_conn].s = nullptr;
-
- bRet = false;
- }
-
- delete pReq;
- return bRet;
-}
-
-void CIcqProto::Push(MHttpRequest *p)
-{
- AsyncHttpRequest *pReq = (AsyncHttpRequest*)p;
-
- pReq->OnPush();
- {
- mir_cslock lck(m_csHttpQueue);
- m_arHttpQueue.insert(pReq);
- }
-
- SetEvent(m_evRequestsQueue);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-AsyncHttpRequest* operator<<(AsyncHttpRequest *pReq, const AIMSID ¶m)
-{
- pReq << CHAR_PARAM("f", "json") << CHAR_PARAM("aimsid", param.m_ppro->m_aimsid) << CHAR_PARAM("r", pReq->m_reqId);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- return pReq;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-MHttpRequest* operator<<(MHttpRequest *pReq, const GROUP_PARAM ¶m)
-{
- if (param.wszValue) {
- CMStringW tmp(param.wszValue);
- tmp.Replace(L"\\", L">");
- tmp.Replace(L"/", L">");
- pReq << WCHAR_PARAM(param.szName, tmp);
- }
- return pReq;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-JsonReply::JsonReply(MHttpResponse *pReply)
-{
- if (pReply == nullptr) {
- m_errorCode = 500;
- return;
- }
-
- m_errorCode = pReply->resultCode;
- if (m_errorCode != 200)
- return;
-
- m_root = json_parse(pReply->body);
- if (m_root == nullptr) {
- m_errorCode = 500;
- return;
- }
-
- JSONNode &response = (*m_root)["response"];
- m_errorCode = response["statusCode"].as_int();
- m_requestId = response["requestId"].as_mstring();
- m_detailCode = response["statusDetailCode"].as_int();
- m_data = &response["data"];
-}
-
-JsonReply::~JsonReply()
-{
- json_delete(m_root);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-FileReply::FileReply(MHttpResponse *pReply)
-{
- if (pReply == nullptr) {
- m_errorCode = 500;
- return;
- }
-
- m_errorCode = pReply->resultCode;
- if (m_errorCode != 200)
- return;
-
- m_root = json_parse(pReply->body);
- if (m_root == nullptr) {
- m_errorCode = 500;
- return;
- }
-
- m_errorCode = (*m_root)["status"].as_int();
- m_data = &(*m_root)["data"];
-}
-
-FileReply::~FileReply()
-{
- json_delete(m_root);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-RobustReply::RobustReply(MHttpResponse *pReply)
-{
- if (pReply == nullptr) {
- m_errorCode = 500;
- return;
- }
-
- m_errorCode = pReply->resultCode;
- if (m_errorCode != 200)
- return;
-
- m_root = json_parse(pReply->body);
- if (m_root == nullptr) {
- m_errorCode = 500;
- return;
- }
-
- m_errorCode = (*m_root)["status"]["code"].as_int();
- m_result = &(*m_root)["result"];
- m_results = &(*m_root)["results"];
-}
-
-RobustReply::~RobustReply()
-{
- json_delete(m_root);
-}
diff --git a/protocols/ICQ-WIM/src/http.h b/protocols/ICQ-WIM/src/http.h deleted file mode 100644 index 2191eb1174..0000000000 --- a/protocols/ICQ-WIM/src/http.h +++ /dev/null @@ -1,89 +0,0 @@ - -class CIcqProto; - -enum IcqConnection -{ - CONN_OLD = -2, CONN_NONE = -1, CONN_MAIN = 0, CONN_FETCH = 1, CONN_RAPI = 2, CONN_LAST = 3 -}; - -struct AsyncHttpRequest : public MTHttpRequest<CIcqProto> -{ - IcqConnection m_conn; - MCONTACT hContact; - char m_reqId[50]; - - AsyncHttpRequest(IcqConnection, int type, const char *szUrl, MTHttpRequestHandler pFunc = nullptr); - - void ReplaceJsonParam(const JSONNode&); - - virtual void OnPush() {}; -}; - -struct AsyncRapiRequest : public AsyncHttpRequest -{ - JSONNode request, params; - - AsyncRapiRequest(CIcqProto *ppro, const char *pszMethod, MTHttpRequestHandler pFunc = nullptr, int mode = -1); - - void OnPush() override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -struct GROUP_PARAM : public WCHAR_PARAM -{ - __forceinline GROUP_PARAM(const char *p1, const wchar_t *p2) : - WCHAR_PARAM(p1, p2) - {} -}; - -MHttpRequest* operator<<(MHttpRequest *pReq, const GROUP_PARAM ¶m); - -///////////////////////////////////////////////////////////////////////////////////////// - -class JsonReply -{ - JSONNode *m_root = nullptr; - int m_errorCode = 0, m_detailCode = 0; - JSONNode* m_data = nullptr; - CMStringA m_requestId; - -public: - JsonReply(MHttpResponse*); - ~JsonReply(); - - __forceinline const CMStringA& requestId() const { return m_requestId; } - __forceinline JSONNode& data() const { return *m_data; } - __forceinline int error() const { return m_errorCode; } - __forceinline int detail() const { return m_detailCode; } -}; - -class FileReply -{ - JSONNode *m_root = nullptr; - int m_errorCode = 0; - JSONNode* m_data = nullptr; - -public: - FileReply(MHttpResponse*); - ~FileReply(); - - __forceinline JSONNode& data() const { return *m_data; } - __forceinline int error() const { return m_errorCode; } -}; - -class RobustReply -{ - JSONNode *m_root = nullptr; - int m_errorCode = 0; - JSONNode *m_result = nullptr; - JSONNode *m_results = nullptr; - -public: - RobustReply(MHttpResponse*); - ~RobustReply(); - - __forceinline JSONNode &result() const { return *m_result; } - __forceinline JSONNode &results() const { return *m_results; } - __forceinline int error() const { return m_errorCode; } -}; diff --git a/protocols/ICQ-WIM/src/ignore.cpp b/protocols/ICQ-WIM/src/ignore.cpp deleted file mode 100644 index deff7a5d36..0000000000 --- a/protocols/ICQ-WIM/src/ignore.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// Server permissions
-
-#include "stdafx.h"
-
-void CIcqProto::GetPermitDeny()
-{
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/preference/getPermitDeny", &CIcqProto::OnGetPermitDeny) << AIMSID(this));
-}
-
-void CIcqProto::OnGetPermitDeny(MHttpResponse *pReply, AsyncHttpRequest*)
-{
- JsonReply root(pReply);
- if (root.error() == 200)
- ProcessPermissions(root.data());
-}
-
-void CIcqProto::ProcessPermissions(const JSONNode &ev)
-{
- { mir_cslock lck(m_csCache);
- for (auto &it : m_arCache)
- it->m_iApparentMode = 0;
- }
-
- for (auto &it : ev["allows"]) {
- auto *p = FindUser(it.as_mstring());
- if (p)
- p->m_iApparentMode = ID_STATUS_ONLINE;
- }
-
- m_bIgnoreListEmpty = true;
- for (auto &it : ev["ignores"]) {
- CMStringW wszId(it.as_mstring());
- auto *p = FindUser(wszId);
- if (p == nullptr) {
- CreateContact(wszId, false);
- p = FindUser(wszId);
- }
- p->m_iApparentMode = ID_STATUS_OFFLINE;
- Contact::Hide(p->m_hContact);
- m_bIgnoreListEmpty = false;
- }
-}
-
-void CIcqProto::SetPermitDeny(const CMStringW &userId, bool bAllow)
-{
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/preference/setPermitDeny")
- << AIMSID(this) << WCHAR_PARAM((bAllow) ? "pdIgnoreRemove" : "pdIgnore", userId);
- if (!m_bIgnoreListEmpty)
- pReq << CHAR_PARAM("pdMode", "denySome");
- Push(pReq);
-}
diff --git a/protocols/ICQ-WIM/src/main.cpp b/protocols/ICQ-WIM/src/main.cpp deleted file mode 100644 index bcc74bcbf7..0000000000 --- a/protocols/ICQ-WIM/src/main.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-bool g_bSecureIM, g_bMessageState;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static PLUGININFOEX pluginInfoEx = {
- sizeof(PLUGININFOEX),
- __PLUGIN_NAME,
- PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
- __DESCRIPTION,
- __AUTHOR,
- __COPYRIGHT,
- __AUTHORWEB,
- UNICODE_AWARE,
- { 0xEFB2355B, 0x82B3, 0x4759, { 0xb7, 0xd8, 0x95, 0xf8, 0xe9, 0x50, 0x62, 0x91 } } // {EFB2355B-82B3-4759-B7D8-95F8E9506291}
-};
-
-CMPlugin g_plugin;
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-CMPlugin::CMPlugin() :
- ACCPROTOPLUGIN<CIcqProto>(MODULENAME, pluginInfoEx)
-{
- SetUniqueId(DB_KEY_ID);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST };
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static int ModuleLoad(WPARAM, LPARAM)
-{
- g_bSecureIM = ServiceExists("SecureIM/IsContactSecured");
- g_bMessageState = ServiceExists(MS_MESSAGESTATE_UPDATE);
- return 0;
-}
-
-static int OnModulesLoaded(WPARAM, LPARAM)
-{
- ModuleLoad(0, 0);
- return 0;
-}
-
-static IconItem iconList[] =
-{
- { LPGEN("Forward"), "forward", IDI_FORWARD },
- { LPGEN("E-mail"), "icq_email", IDI_INBOX },
- { LPGEN("E-mail notification"), "icq_email_notif", IDI_MAIL_NOTIFY }
-};
-
-int CMPlugin::Load()
-{
- registerIcon("Protocols/ICQ", iconList, "ICQ");
-
- HookEvent(ME_SYSTEM_MODULELOAD, ModuleLoad);
- HookEvent(ME_SYSTEM_MODULEUNLOAD, ModuleLoad);
- HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
- return 0;
-}
diff --git a/protocols/ICQ-WIM/src/menus.cpp b/protocols/ICQ-WIM/src/menus.cpp deleted file mode 100644 index 392af5f41b..0000000000 --- a/protocols/ICQ-WIM/src/menus.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* -Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org) - -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 version 2 -of the License. - -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, see <http://www.gnu.org/licenses/>. -*/ - -#include "stdafx.h" - -#define MenuExecService "/NSExecMenu" - -int CIcqProto::OnPrebuildMenu(WPARAM hContact, LPARAM lParam) -{ - if (!Proto_IsProtoOnContact(hContact, m_szModuleName)) { - Menu_ShowItem(hmiForward, false); - Menu_ShowItem(hmiConvert, false); - Menu_ShowItem(hmiFavorites, false); - } - else { - Menu_ShowItem(hmiFavorites, true); - - auto *dbei = (DB::EventInfo *)lParam; - Menu_ShowItem(hmiForward, dbei->eventType == EVENTTYPE_MESSAGE || dbei->eventType == EVENTTYPE_FILE); - - ptrW wszText(dbei->getText()); - Menu_ShowItem(hmiConvert, fileText2url(wszText.get())); - } - return 0; -} - -void CIcqProto::InitMenus() -{ - if (!HookProtoEvent(ME_NS_PREBUILDMENU, &CIcqProto::OnPrebuildMenu)) - return; - - CreateProtoService(MenuExecService, &CIcqProto::SvcExecMenu); - - CMStringA szServiceName(FORMAT, "%s%s", m_szModuleName, MenuExecService); - CMenuItem mi(&g_plugin); - mi.pszService = szServiceName; - - mi.position = 1000000; - mi.hIcolibItem = g_plugin.getIconHandle(IDI_FORWARD); - mi.name.a = LPGEN("Forward"); - hmiForward = Menu_AddNewStoryMenuItem(&mi, 1); - - mi.position++; - mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_ADDCONTACT); - mi.name.a = LPGEN("Add to favorites"); - hmiFavorites = Menu_AddNewStoryMenuItem(&mi, 2); - - mi.position++; - mi.hIcolibItem = Skin_GetIconHandle(SKINICON_EVENT_FILE); - mi.name.a = LPGEN("Convert a message into a file transfer"); - hmiConvert = Menu_AddNewStoryMenuItem(&mi, 3); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Dialog for message forwarding - -class CForwardDlg : public CIcqDlgBase -{ - CCtrlClc m_clist; - MEVENT m_hEvent; - - void FilterList(CCtrlClc *) - { - for (auto &hContact : Contacts()) - if (!Proto_IsProtoOnContact(hContact, m_proto->m_szModuleName)) - if (HANDLE hItem = m_clist.FindContact(hContact)) - m_clist.DeleteItem(hItem); - } - - void ResetListOptions(CCtrlClc *) - { - m_clist.SetHideEmptyGroups(true); - m_clist.SetHideOfflineRoot(true); - } - -public: - CForwardDlg(CIcqProto *ppro, MEVENT hEvent) : - CIcqDlgBase(ppro, IDD_FORWARD), - m_hEvent(hEvent), - m_clist(this, IDC_CLIST) - { - m_clist.OnNewContact = - m_clist.OnListRebuilt = Callback(this, &CForwardDlg::FilterList); - m_clist.OnOptionsChanged = Callback(this, &CForwardDlg::ResetListOptions); - } - - bool OnInitDialog() override - { - SetWindowLongPtr(m_clist.GetHwnd(), GWL_STYLE, - GetWindowLongPtr(m_clist.GetHwnd(), GWL_STYLE) | CLS_SHOWHIDDEN | CLS_HIDEOFFLINE | CLS_CHECKBOXES | CLS_HIDEEMPTYGROUPS | CLS_USEGROUPS | CLS_GREYALTERNATE | CLS_GROUPCHECKBOXES); - m_clist.SendMsg(CLM_SETEXSTYLE, CLS_EX_DISABLEDRAGDROP | CLS_EX_TRACKSELECT, 0); - ResetListOptions(&m_clist); - FilterList(&m_clist); - return true; - } - - bool OnApply() override - { - for (auto &hContact : m_proto->AccContacts()) - if (HANDLE hItem = m_clist.FindContact(hContact)) - if (m_clist.GetCheck(hItem)) - m_proto->ForwardMessage(m_hEvent, hContact); - - return true; - } -}; - -void CIcqProto::ForwardMessage(MEVENT hEvent, MCONTACT to) -{ - DB::EventInfo dbei(hEvent); - if (!dbei || !dbei.szId || mir_strcmp(dbei.szModule, m_szModuleName)) - return; - - CMStringW wszId(GetUserId(dbei.hContact)); - ptrW wszText(dbei.getText()); - - JSONNode parts(JSON_ARRAY); - JSONNode msgText; msgText << CHAR_PARAM("mediaType", "forward") << WCHAR_PARAM("sn", wszId) << INT_PARAM("time", dbei.timestamp) - << CHAR_PARAM("msgId", dbei.szId) << WCHAR_PARAM("text", wszText); - parts.push_back(msgText); - - SendMessageParts(to, parts); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CIcqProto::SvcExecMenu(WPARAM iCommand, LPARAM pHandle) -{ - MEVENT hEvent = NS_GetCurrent(HANDLE(pHandle)); - if (!hEvent) - return 0; - - switch (iCommand) { - case 1: // forward message - CForwardDlg(this, hEvent).DoModal(); - break; - - case 2: // Add to favorites - ForwardMessage(hEvent, m_hFavContact); - - case 3: // convert a message into a file transfer - DB::EventInfo dbei(hEvent); - if (!dbei) - return 0; - - IcqFileInfo *pFileInfo = nullptr; - CMStringW wszText(ptrW(dbei.getText())); - if (CheckFile(dbei.hContact, wszText, pFileInfo)) { - if (!pFileInfo || pFileInfo->bIsSticker) { - // sticker is a simple text message prcoessed by SmileyAdd - T2Utf szBody(wszText); - mir_free(dbei.pBlob); - dbei.cbBlob = (int)mir_strlen(szBody.get()); - dbei.pBlob = szBody.detach(); - } - else { - // create the offline file event - dbei.eventType = EVENTTYPE_FILE; - - DB::FILE_BLOB blob(pFileInfo->wszDescr, wszText); - blob.setUrl(pFileInfo->szOrigUrl); - blob.setSize(pFileInfo->dwFileSize); - blob.write(dbei); - } - db_event_edit(hEvent, &dbei); - } - } - return 0; -} diff --git a/protocols/ICQ-WIM/src/mra.cpp b/protocols/ICQ-WIM/src/mra.cpp deleted file mode 100644 index 7b86c30f4e..0000000000 --- a/protocols/ICQ-WIM/src/mra.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/*
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
-
-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 version 2
-of the License.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdafx.h"
-
-void CIcqProto::SendMrimLogin(MHttpResponse *pReply)
-{
- if (pReply) {
- if (!m_szMraCookie.IsEmpty())
- m_szMraCookie += "; ";
- m_szMraCookie += pReply->GetCookies();
- }
-
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, "https://icqapilogin.mail.ru/auth/mrimLogin", &CIcqProto::OnCheckMrimLogin);
- pReq->AddHeader("User-Agent", NETLIB_USER_AGENT);
- if (!m_szMraCookie.IsEmpty())
- pReq->AddHeader("Cookie", m_szMraCookie);
- pReq << CHAR_PARAM("clientName", "webagent") << INT_PARAM("clientVersion", 711) << CHAR_PARAM("devId", APP_ID)
- << CHAR_PARAM("r", "91640-1626423568") << CHAR_PARAM("f", "json");
-#ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
-#endif
- Push(pReq);
-}
-
-void CIcqProto::OnCheckMrimLogin(MHttpResponse *pReply, AsyncHttpRequest *)
-{
- JsonReply root(pReply);
- switch (root.error()) {
- case 200:
- case 302:
- break;
-
- case 460: // no cookies at all, obtain them via MRA auth site
- {
- CMStringW uin(m_szOwnId);
-
- int iStart = 0;
- CMStringW wszLogin = uin.Tokenize(L"@", iStart);
- CMStringW wszDomain = uin.Tokenize(L"@", iStart);
-
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, "https://auth.mail.ru/cgi-bin/auth?from=splash", &CIcqProto::OnCheckMraAuth);
- pReq->AddHeader("User-Agent", NETLIB_USER_AGENT);
- if (!m_szMraCookie.IsEmpty())
- pReq->AddHeader("Cookie", m_szMraCookie);
- pReq << WCHAR_PARAM("Domain", wszDomain) << WCHAR_PARAM("Login", wszLogin) << CHAR_PARAM("Password", m_szPassword)
- << INT_PARAM("new_auth_form", 1) << INT_PARAM("saveauth", 1);
-#ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
-#endif
- Push(pReq);
- }
- return;
-
- case 462: // bad cookies, refresh them
- if (!m_bError462) {
- m_bError462 = true;
-
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, "https://auth.mail.ru/sdc?JSONP_call=jscb_tmp_c85825&from=https%3A%2F%2Ficqapilogin.mail.ru%2Fauth%2FmrimLogin", &CIcqProto::OnCheckMraAuthFinal);
- pReq->flags |= NLHRF_REDIRECT;
- pReq->AddHeader("Cookie", m_szMraCookie);
- pReq->AddHeader("Referer", "https://webagent.mail.ru/");
- pReq->AddHeader("User-Agent", NETLIB_USER_AGENT);
- Push(pReq);
- return;
- }
-
- m_bError462 = false;
- __fallthrough;
-
- default:
- ConnectionFailed(LOGINERR_WRONGPROTOCOL, root.error());
- return;
- }
-
- JSONNode &data = root.data();
- m_szAToken = data["token"]["a"].as_mstring();
- mir_urlDecode(m_szAToken.GetBuffer());
- setString(DB_KEY_ATOKEN, m_szAToken);
-
- m_szSessionKey = data["sessionKey"].as_mstring();
-
- SetOwnId(data["loginId"].as_mstring());
-
- int srvTS = data["hostTime"].as_int();
- m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
-
- StartSession();
-}
-
-void CIcqProto::OnCheckMraAuth(MHttpResponse *pReply, AsyncHttpRequest *)
-{
- JsonReply root(pReply);
- switch (root.error()) {
- case 200:
- case 302:
- m_szMraCookie.Empty();
- SendMrimLogin(pReply);
- break;
-
- default:
- ConnectionFailed(LOGINERR_WRONGPROTOCOL, root.error());
- }
-}
-
-void CIcqProto::OnCheckMraAuthFinal(MHttpResponse *pReply, AsyncHttpRequest *)
-{
- switch (pReply->resultCode) {
- case 200:
- case 302:
- // accumulate sdcs cookie and resend request
- SendMrimLogin(pReply);
- break;
-
- default:
- ConnectionFailed(LOGINERR_WRONGPROTOCOL, 500);
- }
-}
diff --git a/protocols/ICQ-WIM/src/options.cpp b/protocols/ICQ-WIM/src/options.cpp deleted file mode 100644 index ca7603b9bb..0000000000 --- a/protocols/ICQ-WIM/src/options.cpp +++ /dev/null @@ -1,401 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-class CIcqEnterLoginDlg : public CIcqDlgBase
-{
- CCtrlEdit edtPass;
- CCtrlCheck chkSave;
-
-public:
- CIcqEnterLoginDlg(CIcqProto *ppro) :
- CIcqDlgBase(ppro, IDD_LOGINPW),
- edtPass(this, IDC_PASSWORD),
- chkSave(this, IDC_SAVEPASS)
- {
- }
-
- bool OnInitDialog() override
- {
- m_proto->m_bDlgActive = true;
- chkSave.SetState(m_proto->getBool("RememberPass"));
- Window_SetIcon_IcoLib(m_hwnd, m_proto->m_hProtoIcon);
- return true;
- }
-
- bool OnApply() override
- {
- m_proto->setByte("RememberPass", m_proto->m_bRememberPwd = chkSave.GetState());
- m_proto->m_szPassword = ptrA(edtPass.GetTextU());
- EndModal(true);
- return true;
- }
-
- void OnDestroy() override
- {
- m_proto->m_bDlgActive = false;
- }
-};
-
-bool CIcqProto::RetrievePassword()
-{
- // if we registered via phone (i.e., server holds the password), we don't need to enter it
- if (getByte(DB_KEY_PHONEREG))
- return true;
-
- if (!m_szPassword.IsEmpty() && m_bRememberPwd)
- return true;
-
- m_szPassword = getMStringA("Password");
- if (!m_szPassword.IsEmpty()) {
- m_bRememberPwd = true;
- return true;
- }
-
- if (m_bDlgActive)
- return false;
-
- return CIcqEnterLoginDlg(this).DoModal();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-struct CIcqRegistrationDlg : public CIcqDlgBase
-{
- CMStringA szTrans, szMsisdn;
- int iErrorCode = 0;
-
- CCtrlEdit edtPhone, edtCode;
- CCtrlButton btnSendSms;
-
- CIcqRegistrationDlg(CIcqProto *ppro) :
- CIcqDlgBase(ppro, IDD_REGISTER),
- edtPhone(this, IDC_PHONE),
- edtCode(this, IDC_CODE),
- btnSendSms(this, IDC_SENDSMS)
- {
- btnSendSms.OnClick = Callback(this, &CIcqRegistrationDlg::onClick_SendSms);
- edtPhone.OnChange = Callback(this, &CIcqRegistrationDlg::onChange_Phone);
- }
-
- bool OnApply() override
- {
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://u.icq.net/api/v60/smsreg/loginWithPhoneNumber.php", &CIcqProto::OnLoginViaPhone);
- pReq << CHAR_PARAM("locale", "en") << CHAR_PARAM("msisdn", szMsisdn) << CHAR_PARAM("trans_id", szTrans) << CHAR_PARAM("k", APP_ID)
- << CHAR_PARAM("r", pReq->m_reqId) << CHAR_PARAM("f", "json") << WCHAR_PARAM("sms_code", ptrW(edtCode.GetText())) << INT_PARAM("create_account", 1);
- pReq->pUserInfo = this;
-
- SetCursor(LoadCursor(0, IDC_WAIT));
- m_proto->ExecuteRequest(pReq);
- SetCursor(LoadCursor(0, IDC_ARROW));
-
- if (iErrorCode != 200)
- return false;
-
- EndDialog(m_hwnd, 1);
- return true;
- }
-
- void onChange_Phone(CCtrlEdit*)
- {
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://u.icq.net/api/v60/smsapi/fcgi-bin/smsphoneinfo", &CIcqProto::OnCheckPhone);
- pReq << CHAR_PARAM("service", "icq_registration") << CHAR_PARAM("info", "typing_check,score,iso_country_code") << CHAR_PARAM("lang", "ru")
- << WCHAR_PARAM("phone", ptrW(edtPhone.GetText())) << CHAR_PARAM("id", pReq->m_reqId);
- pReq->pUserInfo = this;
- m_proto->Push(pReq);
- }
-
- void onClick_SendSms(CCtrlButton*)
- {
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://u.icq.net/api/v60/smsreg/requestPhoneValidation.php", &CIcqProto::OnValidateSms);
- pReq << CHAR_PARAM("locale", "en") << CHAR_PARAM("msisdn", szMsisdn) << CHAR_PARAM("r", pReq->m_reqId)
- << CHAR_PARAM("smsFormatType", "human") << CHAR_PARAM("k", APP_ID);
- pReq->pUserInfo = this;
- m_proto->Push(pReq);
- }
-};
-
-void CIcqProto::OnCheckPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- if (pReply == nullptr || pReply->resultCode != 200)
- return;
-
- CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo;
- pDlg->btnSendSms.Disable();
- pDlg->edtCode.Disable();
-
- JSONROOT root(pReply->body);
- CMStringW wszStatus((*root)["status"].as_mstring());
- if (wszStatus != L"OK") {
- pDlg->edtCode.SetText((*root)["printable"].as_mstring());
- return;
- }
-
- CMStringA szPhoneNumber((*root)["typing_check"]["modified_phone_number"].as_mstring());
- CMStringA szPrefix((*root)["modified_prefix"].as_mstring());
-
- auto *pNew = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://www.icq.com/smsreg/normalizePhoneNumber.php", &CIcqProto::OnNormalizePhone);
- pNew << CHAR_PARAM("countryCode", szPrefix) << CHAR_PARAM("phoneNumber", szPhoneNumber.c_str() + szPrefix.GetLength())
- << CHAR_PARAM("k", APP_ID) << CHAR_PARAM("r", pReq->m_reqId);
- pNew->pUserInfo = pDlg;
- Push(pNew);
-}
-
-void CIcqProto::OnNormalizePhone(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo;
-
- JsonReply root(pReply);
- pDlg->iErrorCode = root.error();
- if (root.error() != 200)
- return;
-
- const JSONNode &data = root.data();
- pDlg->szMsisdn = data["msisdn"].as_mstring();
- pDlg->btnSendSms.Enable();
-}
-
-void CIcqProto::OnValidateSms(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- JsonReply root(pReply);
- if (root.error() != 200)
- return;
-
- CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo;
- const JSONNode &data = root.data();
- pDlg->szTrans = data["trans_id"].as_mstring();
-
- pDlg->edtCode.Enable();
- pDlg->edtCode.SetText(L"");
-}
-
-void CIcqProto::OnLoginViaPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- CIcqRegistrationDlg *pDlg = (CIcqRegistrationDlg*)pReq->pUserInfo;
-
- JsonReply root(pReply);
- pDlg->iErrorCode = root.error();
- if (root.error() != 200)
- return;
-
- const JSONNode &data = root.data();
- m_szAToken = data["token"]["a"].as_mstring();
- mir_urlDecode(m_szAToken.GetBuffer());
- setString(DB_KEY_ATOKEN, m_szAToken);
-
- int srvTS = data["hostTime"].as_int();
- m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
-
- m_szSessionKey = data["sessionKey"].as_mstring();
- setString(DB_KEY_SESSIONKEY, m_szSessionKey);
-
- SetOwnId(data["loginId"].as_mstring());
- setByte(DB_KEY_PHONEREG, 1);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-class COptionsDlg : public CIcqDlgBase
-{
- CCtrlEdit edtUin, edtPassword;
- CCtrlCheck chkHideChats, chkTrayIcon, chkLaunchMailbox, chkShowErrorPopups;
- CCtrlButton btnCreate;
- CMStringW wszOldPass;
-
-public:
- COptionsDlg(CIcqProto *ppro, int iDlgID, bool bFullDlg) :
- CIcqDlgBase(ppro, iDlgID),
- edtUin(this, IDC_UIN),
- btnCreate(this, IDC_REGISTER),
- edtPassword(this, IDC_PASSWORD),
- chkTrayIcon(this, IDC_USETRAYICON),
- chkHideChats(this, IDC_HIDECHATS),
- chkLaunchMailbox(this, IDC_LAUNCH_MAILBOX),
- chkShowErrorPopups(this, IDC_SHOWERRORPOPUPS)
- {
- btnCreate.OnClick = Callback(this, &COptionsDlg::onClick_Register);
-
- CreateLink(edtUin, ppro->m_szOwnId);
- if (bFullDlg) {
- CreateLink(chkHideChats, ppro->m_bHideGroupchats);
- CreateLink(chkTrayIcon, ppro->m_bUseTrayIcon);
- CreateLink(chkLaunchMailbox, ppro->m_bLaunchMailbox);
- CreateLink(chkShowErrorPopups, ppro->m_bErrorPopups);
-
- chkTrayIcon.OnChange = Callback(this, &COptionsDlg::onChange_Tray);
- }
- }
-
- bool OnInitDialog() override
- {
- btnCreate.Hide();
-
- wszOldPass = m_proto->getMStringW("Password");
- edtPassword.SetText(wszOldPass);
- return true;
- }
-
- bool OnApply() override
- {
- ptrW wszPass(edtPassword.GetText());
- if (wszPass)
- m_proto->setWString("Password", wszPass);
- else
- m_proto->delSetting("Password");
-
- if (wszOldPass != wszPass) {
- m_proto->delSetting(DB_KEY_ATOKEN);
- m_proto->delSetting(DB_KEY_SESSIONKEY);
- m_proto->delSetting(DB_KEY_PHONEREG);
- }
-
- if (mir_wstrlen(wszPass)) {
- m_proto->m_szPassword = T2Utf(wszPass).get();
- m_proto->m_bRememberPwd = true;
- }
- else m_proto->m_bRememberPwd = m_proto->getByte("RememberPass");
-
- return true;
- }
-
- void onChange_Tray(CCtrlCheck*)
- {
- chkLaunchMailbox.Enable(chkTrayIcon.GetState());
- }
-
- void onClick_Register(CCtrlButton*)
- {
- CIcqRegistrationDlg dlg(m_proto);
- dlg.SetParent(m_hwnd);
- if (dlg.DoModal()) // force exit to avoid data corruption
- PostMessage(m_hwndParent, WM_COMMAND, MAKELONG(IDCANCEL, BN_CLICKED), 0);
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Advanced options
-
-class CAdvOptionsDlg : public CIcqDlgBase
-{
- CCtrlEdit edtDiff1, edtDiff2;
- CCtrlSpin spin1, spin2;
- CCtrlCombo cmbStatus1, cmbStatus2;
-
-public:
- CAdvOptionsDlg(CIcqProto *ppro) :
- CIcqDlgBase(ppro, IDD_OPTIONS_ADV),
- spin1(this, IDC_SPIN1, 32000),
- spin2(this, IDC_SPIN2, 32000),
- edtDiff1(this, IDC_DIFF1),
- edtDiff2(this, IDC_DIFF2),
- cmbStatus1(this, IDC_STATUS1),
- cmbStatus2(this, IDC_STATUS2)
- {
- edtDiff1.OnChange = Callback(this, &CAdvOptionsDlg::onChange_Timeout1);
- edtDiff2.OnChange = Callback(this, &CAdvOptionsDlg::onChange_Timeout2);
-
- spin1.OnChange = Callback(this, &CAdvOptionsDlg::onChange_Spin1);
- spin2.OnChange = Callback(this, &CAdvOptionsDlg::onChange_Spin2);
-
- CreateLink(spin1, ppro->m_iTimeDiff1);
- CreateLink(spin2, ppro->m_iTimeDiff2);
- }
-
- bool OnInitDialog() override
- {
- for (uint32_t iStatus = ID_STATUS_OFFLINE; iStatus <= ID_STATUS_MAX; iStatus++) {
- int idx = cmbStatus1.AddString(Clist_GetStatusModeDescription(iStatus, 0), iStatus);
- if (iStatus == m_proto->m_iStatus1)
- cmbStatus1.SetCurSel(idx);
-
- idx = cmbStatus2.AddString(Clist_GetStatusModeDescription(iStatus, 0), iStatus);
- if (iStatus == m_proto->m_iStatus2)
- cmbStatus2.SetCurSel(idx);
- }
-
- return true;
- }
-
- bool OnApply() override
- {
- m_proto->m_iStatus1 = cmbStatus1.GetCurData();
- m_proto->m_iStatus2 = cmbStatus2.GetCurData();
- return true;
- }
-
- void onChange_Value1(int val)
- {
- bool bEnabled = val != 0;
- spin2.Enable(bEnabled);
- edtDiff2.Enable(bEnabled);
- cmbStatus1.Enable(bEnabled);
- cmbStatus2.Enable(bEnabled && spin2.GetPosition() != 0);
- }
-
- void onChange_Timeout1(CCtrlEdit *)
- {
- onChange_Value1(edtDiff1.GetInt());
- }
-
- void onChange_Spin1(CCtrlEdit *)
- {
- onChange_Value1(spin1.GetPosition());
- }
-
- void onChange_Timeout2(CCtrlEdit *)
- {
- cmbStatus2.Enable(edtDiff1.GetInt() != 0 && edtDiff2.GetInt() != 0);
- }
-
- void onChange_Spin2(CCtrlEdit *)
- {
- cmbStatus2.Enable(spin1.GetPosition() != 0 && spin2.GetPosition() != 0);
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Services
-
-MWindow CIcqProto::OnCreateAccMgrUI(MWindow hwndParent)
-{
- COptionsDlg *pDlg = new COptionsDlg(this, IDD_OPTIONS_ACCMGR, false);
- pDlg->SetParent(hwndParent);
- pDlg->Create();
- return pDlg->GetHwnd();
-}
-
-int CIcqProto::OnOptionsInit(WPARAM wParam, LPARAM)
-{
- OPTIONSDIALOGPAGE odp = {};
- odp.szTitle.w = m_tszUserName;
- odp.flags = ODPF_UNICODE | ODPF_BOLDGROUPS;
- odp.szGroup.w = LPGENW("Network");
- odp.position = 1;
-
- odp.szTab.w = LPGENW("General");
- odp.pDialog = new COptionsDlg(this, IDD_OPTIONS_FULL, true);
- g_plugin.addOptions(wParam, &odp);
-
- odp.szTab.w = LPGENW("Advanced");
- odp.pDialog = new CAdvOptionsDlg(this);
- g_plugin.addOptions(wParam, &odp);
- return 0;
-}
diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp deleted file mode 100644 index 812261fdde..0000000000 --- a/protocols/ICQ-WIM/src/poll.cpp +++ /dev/null @@ -1,415 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// Long-poll thread and its item handlers
-
-#include "stdafx.h"
-
-void CIcqProto::ProcessBuddyList(const JSONNode &ev)
-{
- m_arGroups.destroy();
-
- LIST<IcqGroup> tmpGroups(10);
- bool bEnableMenu = false;
-
- for (auto &it : ev["groups"]) {
- auto *pGroup = new IcqGroup(it["id"].as_int(), it["name"].as_mstring());
- debugLogA("new group: id=%d, level=%d, name=%S", pGroup->id, pGroup->level, pGroup->wszName.c_str());
- if (pGroup->level != 0) {
- for (auto &p : tmpGroups.rev_iter()) {
- if (p->level == pGroup->level-1) {
- pGroup->wszName = p->wszName + L"\\" + pGroup->wszName;
- debugLogA("Group name fixed as %S", pGroup->wszName.c_str());
- break;
- }
- }
- }
- tmpGroups.insert(pGroup);
- m_arGroups.insert(pGroup);
-
- bool bCreated = false;
-
- for (auto &buddy : it["buddies"]) {
- MCONTACT hContact = ParseBuddyInfo(buddy);
- if (hContact == INVALID_CONTACT_ID)
- continue;
-
- ProcessOnline(buddy, hContact);
- setWString(hContact, "IcqGroup", pGroup->wszName);
-
- if (!bCreated) {
- Clist_GroupCreate(0, pGroup->wszName);
- bCreated = true;
- }
-
- ptrW mirGroup(Clist_GetGroup(hContact));
- if (mir_wstrcmp(mirGroup, pGroup->wszName))
- bEnableMenu = true;
-
- if (!mirGroup)
- Clist_SetGroup(hContact, pGroup->wszName);
- }
- }
-
- if (bEnableMenu)
- Menu_ShowItem(m_hUploadGroups, true);
-
- mir_cslock lck(m_csCache);
- for (auto &it : m_arCache)
- if (!it->m_bInList && !getBool(it->m_hContact, "IcqDeleted"))
- Contact::RemoveFromList(it->m_hContact);
-}
-
-void CIcqProto::ProcessDiff(const JSONNode &ev)
-{
- for (auto &block : ev) {
- CMStringW szType = block["type"].as_mstring();
- if (szType != "updated" && szType != "created" && szType != "deleted")
- continue;
-
- for (auto &it : block["data"]) {
- int grpId = it["id"].as_int();
- CMStringW wszName = it["name"].as_mstring();
-
- auto *pGroup = m_arGroups.find((IcqGroup *)&grpId);
- if (pGroup == nullptr) {
- if (szType != "created") {
- debugLogA("Group %d isn't found", grpId);
- continue;
- }
-
- pGroup = new IcqGroup(grpId, wszName);
- m_arGroups.insert(pGroup);
- }
- else {
- pGroup->wszSrvName = wszName;
- pGroup->SetName(wszName);
- }
-
- bool bCreated = false, bDeleted = (szType == "deleted");
-
- int iProcessed = 0;
- for (auto &buddy : it["buddies"]) {
- MCONTACT hContact = ParseBuddyInfo(buddy, true);
- if (hContact == INVALID_CONTACT_ID)
- continue;
-
- iProcessed++;
- if (bDeleted) {
- db_delete_contact(hContact, CDF_FROM_SERVER);
- continue;
- }
-
- ProcessOnline(buddy, hContact);
- setWString(hContact, "IcqGroup", pGroup->wszName);
-
- if (!bCreated) {
- Clist_GroupCreate(0, pGroup->wszName);
- bCreated = true;
- }
-
- ptrW wszGroup(Clist_GetGroup(hContact));
- if (!wszGroup)
- Clist_SetGroup(hContact, pGroup->wszName);
- }
-
- if (bDeleted && !iProcessed)
- m_arGroups.remove(pGroup);
- }
-
- RefreshGroups();
- }
-}
-
-void CIcqProto::ProcessEvent(const JSONNode &ev)
-{
- const JSONNode &pData = ev["eventData"];
- CMStringW szType = ev["type"].as_mstring();
- if (szType == L"buddylist")
- ProcessBuddyList(pData);
- else if (szType == L"diff")
- ProcessDiff(pData);
- else if (szType == L"histDlgState")
- ProcessHistData(pData);
- else if (szType == L"imState")
- ProcessImState(pData);
- else if (szType == L"mchat")
- ProcessGroupChat(pData);
- else if (szType == L"myInfo")
- ProcessMyInfo(pData);
- else if (szType == L"notification")
- ProcessNotification(pData);
- else if (szType == L"permitDeny")
- ProcessPermissions(pData);
- else if (szType == L"presence")
- ProcessPresence(pData);
- else if (szType == L"sessionEnded")
- ProcessSessionEnd(pData);
- else if (szType == L"typing")
- ProcessTyping(pData);
-}
-
-void CIcqProto::ProcessHistData(const JSONNode &ev)
-{
- MCONTACT hContact;
- bool bVeryBeginning = m_bFirstBos;
-
- CMStringW wszId(ev["sn"].as_mstring());
- auto *pUser = FindUser(wszId); // might be NULL for groupchats
-
- if (IsChat(wszId)) {
- SESSION_INFO *si = Chat_Find(wszId, m_szModuleName);
- if (si == nullptr) {
- CMStringW wszNick;
- for (auto &it : ev["persons"])
- if (it["sn"].as_mstring() == wszId) {
- wszNick = it["friendly"].as_mstring();
- break;
- }
-
- if ((si = GcCreate(wszId, wszNick)) == nullptr)
- return;
- }
-
- hContact = si->hContact;
-
- __int64 srvInfoVer = _wtoi64(ev["mchatState"]["infoVersion"].as_mstring());
- __int64 srvMembersVer = _wtoi64(ev["mchatState"]["membersVersion"].as_mstring());
- if (srvInfoVer != getId(hContact, "InfoVersion") || srvMembersVer != getId(hContact, "MembersVersion") || si->arUsers.getCount() == 0)
- RetrieveChatInfo(hContact);
- }
- else {
- hContact = CreateContact(wszId, true);
-
- // for temporary contacts that just gonna be created
- if (pUser == nullptr) {
- bVeryBeginning = true;
- pUser = FindUser(wszId);
- }
- }
-
- // restore reading from the previous point, if we just installed Miranda
- __int64 lastMsgId = getId(hContact, DB_KEY_LASTMSGID);
- if (lastMsgId == 0) {
- lastMsgId = _wtoi64(ev["yours"]["lastRead"].as_mstring());
- setId(hContact, DB_KEY_LASTMSGID, lastMsgId);
- }
-
- if (pUser && pUser->m_bSkipPatch) {
- pUser->m_bSkipPatch = false;
- goto LBL_SkipPatch;
- }
-
- ProcessPatchVersion(hContact, _wtoi64(ev["patchVersion"].as_mstring()));
-LBL_SkipPatch:
-
- __int64 srvLastId = _wtoi64(ev["lastMsgId"].as_mstring());
-
- // we load history in the very beginning or if the previous message
- if (bVeryBeginning) {
- if (pUser) {
- debugLogA("Setting cache = %lld for %d", srvLastId, hContact);
- pUser->m_iProcessedMsgId = srvLastId;
- }
-
- if (srvLastId > lastMsgId) {
- debugLogA("We need to retrieve history for %S: %lld > %lld", wszId.c_str(), srvLastId, lastMsgId);
- RetrieveUserHistory(hContact, lastMsgId, false);
- }
- }
- else {
- if (!(pUser && pUser->m_iProcessedMsgId >= srvLastId)) {
- if (pUser)
- debugLogA("Proceeding with cache for %d: %lld < %lld", hContact, pUser->m_iProcessedMsgId, srvLastId);
- else
- debugLogA("Proceeding with empty cache for %d", hContact);
-
- for (auto &it : ev["intro"]["messages"])
- ParseMessage(hContact, lastMsgId, it, 0);
-
- for (auto &it : ev["tail"]["messages"])
- ParseMessage(hContact, lastMsgId, it, PM::LocalTime);
-
- setId(hContact, DB_KEY_LASTMSGID, lastMsgId);
- if (pUser) {
- pUser->m_iProcessedMsgId = lastMsgId;
- debugLogA("Setting second cache = %lld for %d", srvLastId, hContact);
- }
- }
- }
-
- // check remote read
- if (g_bMessageState) {
- __int64 srvRemoteRead = _wtoi64(ev["theirs"]["lastRead"].as_mstring());
- __int64 lastRemoteRead = getId(hContact, DB_KEY_REMOTEREAD);
- if (srvRemoteRead > lastRemoteRead) {
- setId(hContact, DB_KEY_REMOTEREAD, srvRemoteRead);
-
- if (g_bMessageState)
- CallService(MS_MESSAGESTATE_UPDATE, hContact, MRD_TYPE_READ);
- }
- }
-}
-
-void CIcqProto::ProcessImState(const JSONNode &ev)
-{
- for (auto &it : ev["imStates"]) {
- if (it["state"].as_mstring() != L"delivered")
- continue;
-
- CMStringA reqId(it["sendReqId"].as_mstring());
- CMStringA msgId(it["histMsgId"].as_mstring());
- MCONTACT hContact = CheckOwnMessage(reqId, msgId, false);
- if (hContact)
- CheckLastId(hContact, ev);
- }
-}
-
-void CIcqProto::ProcessMyInfo(const JSONNode &ev)
-{
- Json2string(0, ev, "friendly", "Nick", true);
- Json2string(0, ev, "attachedPhoneNumber", DB_KEY_PHONE, true);
-
- CheckAvatarChange(0, ev);
-}
-
-void CIcqProto::ProcessNotification(const JSONNode &ev)
-{
- for (auto &fld : ev["fields"]) {
- const JSONNode &email = fld["mailbox.newMessage"];
- if (email) {
- JSONROOT root(email.as_string().c_str());
- CMStringW wszFrom((*root)["from"].as_mstring());
- CMStringW wszSubj((*root)["subject"].as_mstring());
- m_unreadEmails = (*root)["unreadCount"].as_int();
- debugLogW(L"You received e-mail (%d) from <%s>: <%s>", m_unreadEmails, wszFrom.c_str(), wszSubj.c_str());
-
- CMStringW wszMessage(FORMAT, TranslateT("You received e-mail from %s: %s"), wszFrom.c_str(), wszSubj.c_str());
- EmailNotification(wszMessage);
- }
-
- const JSONNode &status = fld["mailbox.status"];
- if (status) {
- int iOldCount = m_unreadEmails;
-
- JSONROOT root(status.as_string().c_str());
- m_szMailBox = (*root)["email"].as_mstring();
- m_unreadEmails = (*root)["unreadCount"].as_int();
-
- // we've read/removed some messages from server
- if (iOldCount > m_unreadEmails) {
- Clist_RemoveEvent(0, ICQ_FAKE_EVENT_ID);
- return;
- }
-
- // we notify about initial mail count only during login
- if (m_bFirstBos && m_unreadEmails > 0) {
- CMStringW wszMessage(FORMAT, TranslateT("You have %d unread emails"), m_unreadEmails);
- EmailNotification(wszMessage);
- }
- }
- }
-}
-
-void CIcqProto::ProcessPresence(const JSONNode &ev)
-{
- CMStringW aimId = ev["aimId"].as_mstring();
-
- auto *pUser = FindUser(aimId);
- if (pUser == nullptr)
- return;
-
- MCONTACT hContact = GetRealContact(pUser);
- int iNewStatus = StatusFromPresence(ev, hContact);
- if (iNewStatus != -1)
- ProcessStatus(pUser, iNewStatus);
-
- if (hContact != m_hFavContact)
- Json2string(hContact, ev, "friendly", "Nick", true);
- CheckAvatarChange(hContact, ev);
-}
-
-void CIcqProto::ProcessSessionEnd(const JSONNode &/*ev*/)
-{
- m_szRToken.Empty();
- m_iRClientId = 0;
- delSetting(DB_KEY_RCLIENTID);
-
- ShutdownSession();
-}
-
-void CIcqProto::ProcessTyping(const JSONNode &ev)
-{
- CMStringW aimId = ev["aimId"].as_mstring();
- CMStringW wszStatus = ev["typingStatus"].as_mstring();
-
- auto *pUser = FindUser(aimId);
- if (pUser) {
- MCONTACT hContact = GetRealContact(pUser);
- if (wszStatus == "typing")
- CallService(MS_PROTO_CONTACTISTYPING, hContact, 60);
- else
- CallService(MS_PROTO_CONTACTISTYPING, hContact, PROTOTYPE_CONTACTTYPING_OFF);
- }
-}
-
-void CIcqProto::OnFetchEvents(MHttpResponse *pReply, AsyncHttpRequest*)
-{
- JsonReply root(pReply);
- if (root.error() != 200) {
- ShutdownSession();
- return;
- }
-
- JSONNode &data = root.data();
- m_fetchBaseURL = data["fetchBaseURL"].as_mstring();
-
- for (auto &it : data["events"])
- ProcessEvent(it);
-}
-
-void __cdecl CIcqProto::PollThread(void*)
-{
- debugLogA("Polling thread started");
- m_bFirstBos = true;
-
- while (m_bOnline && !m_fetchBaseURL.IsEmpty()) {
- CMStringA szUrl = m_fetchBaseURL;
- if (m_bFirstBos)
- szUrl.Append("&first=1");
- else
- szUrl.Append("&timeout=25000");
-
- if (m_bInvisible)
- szUrl.Append("&bg=1&hidden=1");
-
- auto *pReq = new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, szUrl, &CIcqProto::OnFetchEvents);
- if (!m_bFirstBos)
- pReq->timeout = 62000;
-
- if (!ExecuteRequest(pReq)) {
- ShutdownSession();
- break;
- }
-
- m_bFirstBos = false;
- }
-
- debugLogA("Polling thread ended");
-}
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp deleted file mode 100644 index d224b7d265..0000000000 --- a/protocols/ICQ-WIM/src/proto.cpp +++ /dev/null @@ -1,725 +0,0 @@ -// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera, George Hazan
-// Copyright © 2012-2024 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Protocol Interface Implementation
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#include "m_icolib.h"
-
-#pragma warning(disable:4355)
-
-static int CompareCache(const IcqUser *p1, const IcqUser *p2)
-{
- return mir_wstrcmp(p1->m_aimid, p2->m_aimid);
-}
-
-CIcqProto::CIcqProto(const char *aProtoName, const wchar_t *aUserName) :
- PROTO<CIcqProto>(aProtoName, aUserName),
- m_impl(*this),
- m_arHttpQueue(10),
- m_arOwnIds(1, PtrKeySortT),
- m_arCache(20, &CompareCache),
- m_arGroups(10, NumericKeySortT),
- m_arDeleteQueue(10),
- m_arMarkReadQueue(10, NumericKeySortT),
- m_evRequestsQueue(CreateEvent(nullptr, FALSE, FALSE, nullptr)),
- m_szOwnId(this, DB_KEY_ID),
- m_iStatus1(this, "Status1", ID_STATUS_AWAY),
- m_iStatus2(this, "Status2", ID_STATUS_NA),
- m_iTimeDiff1(this, "TimeDiff1", 0),
- m_iTimeDiff2(this, "TimeDiff2", 0),
- m_bHideGroupchats(this, "HideChats", true),
- m_bUseTrayIcon(this, "UseTrayIcon", false),
- m_bErrorPopups(this, "ShowErrorPopups", true),
- m_bLaunchMailbox(this, "LaunchMailbox", true)
-{
- db_set_resident(m_szModuleName, DB_KEY_ONLINETS);
-
- g_plugin.addPopupOption(CMStringW(FORMAT, TranslateT("%s error notifications"), m_tszUserName), m_bErrorPopups);
-
- // services
- CreateProtoService(PS_GETAVATARCAPS, &CIcqProto::GetAvatarCaps);
- CreateProtoService(PS_GETAVATARINFO, &CIcqProto::GetAvatarInfo);
- CreateProtoService(PS_GETMYAVATAR, &CIcqProto::GetAvatar);
- CreateProtoService(PS_SETMYAVATAR, &CIcqProto::SetAvatar);
-
- CreateProtoService(PS_MENU_LOADHISTORY, &CIcqProto::SvcLoadHistory);
- CreateProtoService(PS_EMPTY_SRV_HISTORY, &CIcqProto::SvcEmptyHistory);
-
- CreateProtoService(PS_GETUNREADEMAILCOUNT, &CIcqProto::SvcGetEmailCount);
- CreateProtoService(PS_GOTO_INBOX, &CIcqProto::SvcGotoInbox);
-
- // cloud file transfer
- CreateProtoService(PS_OFFLINEFILE, &CIcqProto::SvcOfflineFile);
-
- // events
- HookProtoEvent(ME_CLIST_GROUPCHANGE, &CIcqProto::OnGroupChange);
- HookProtoEvent(ME_GC_EVENT, &CIcqProto::GcEventHook);
- HookProtoEvent(ME_GC_BUILDMENU, &CIcqProto::GcMenuHook);
- HookProtoEvent(ME_OPT_INITIALISE, &CIcqProto::OnOptionsInit);
-
- // group chats
- GCREGISTER gcr = {};
- gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_DATABASE | GC_PERSISTENT;
- gcr.ptszDispName = m_tszUserName;
- gcr.pszModule = m_szModuleName;
- Chat_Register(&gcr);
-
- CreateProtoService(PS_LEAVECHAT, &CIcqProto::SvcLeaveChat);
-
- // avatars
- CreateDirectoryTreeW(GetAvatarPath());
-
- // netlib handle
- NETLIBUSER nlu = {};
- nlu.szSettingsModule = m_szModuleName;
- nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE;
- nlu.szDescriptiveName.w = m_tszUserName;
- m_hNetlibUser = Netlib_RegisterUser(&nlu);
-
- // this was previously an old ICQ account
- ptrW wszUin(GetUIN(0));
- if (wszUin != nullptr) {
- delSetting("UIN");
-
- m_szOwnId = wszUin;
-
- for (auto &it : AccContacts())
- delSetting(it, "e-mail");
- }
- // this was previously an old MRA account
- else {
- CMStringW wszEmail(getMStringW("e-mail"));
- if (!wszEmail.IsEmpty()) {
- m_szOwnId = wszEmail;
- delSetting("e-mail");
- }
- }
-
- m_hWorkerThread = ForkThreadEx(&CIcqProto::ServerThread, nullptr, nullptr);
-}
-
-CIcqProto::~CIcqProto()
-{
- ::CloseHandle(m_evRequestsQueue);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// OnModulesLoadedEx - performs hook registration
-
-void CIcqProto::OnModulesLoaded()
-{
- InitMenus();
-
- HookProtoEvent(ME_USERINFO_INITIALISE, &CIcqProto::OnUserInfoInit);
-
- // load custom smilies
- SmileyAdd_LoadContactSmileys(SMADD_FOLDER, m_szModuleName, GetAvatarPath() + L"\\Stickers\\*.png");
-}
-
-void CIcqProto::OnShutdown()
-{
- m_bTerminated = true;
-}
-
-void CIcqProto::OnCacheInit()
-{
- mir_cslock l(m_csCache);
- for (auto &it : AccContacts()) {
- m_bCacheInited = true;
-
- if (isChatRoom(it))
- continue;
-
- // that was previously an ICQ contact
- ptrW wszUin(GetUIN(it));
- if (wszUin != nullptr) {
- delSetting(it, "UIN");
- setWString(it, DB_KEY_ID, wszUin);
- }
- // that was previously a MRA contact
- else {
- CMStringW wszEmail(getMStringW(it, "e-mail"));
- if (!wszEmail.IsEmpty()) {
- delSetting(it, "e-mail");
- setWString(it, DB_KEY_ID, wszEmail);
- }
- }
-
- CMStringW wszId = GetUserId(it);
- auto *pUser = FindUser(wszId);
- if (pUser == nullptr) {
- pUser = new IcqUser(wszId, it);
-
- mir_cslock lck(m_csCache);
- m_arCache.insert(pUser);
- }
- pUser->m_iProcessedMsgId = getId(it, DB_KEY_LASTMSGID);
- }
-}
-
-void CIcqProto::OnContactAdded(MCONTACT hContact)
-{
- CMStringW wszId(getMStringW(hContact, DB_KEY_ID));
- if (!wszId.IsEmpty() && !FindUser(wszId)) {
- mir_cslock l(m_csCache);
- m_arCache.insert(new IcqUser(wszId, hContact));
- }
-}
-
-bool CIcqProto::OnContactDeleted(MCONTACT hContact, uint32_t flags)
-{
- if (flags & CDF_DEL_CONTACT) {
- CMStringW szId(GetUserId(hContact));
- if (!isChatRoom(hContact)) {
- mir_cslock lck(m_csCache);
- m_arCache.remove(FindUser(szId));
- }
-
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/removeBuddy")
- << AIMSID(this) << WCHAR_PARAM("buddy", szId) << INT_PARAM("allGroups", 1));
- }
- return true;
-}
-
-void CIcqProto::OnReceiveOfflineFile(DB::FILE_BLOB &blob)
-{
- if (auto *pFileInfo = (IcqFileInfo *)blob.getUserInfo()) {
- blob.setUrl(pFileInfo->szOrigUrl);
- blob.setSize(pFileInfo->dwFileSize);
- delete pFileInfo;
- }
-}
-
-void CIcqProto::OnSendOfflineFile(DB::EventInfo &dbei, DB::FILE_BLOB &blob, void *hTransfer)
-{
- auto *ft = (IcqFileTransfer *)hTransfer;
-
- if (!ft->m_szMsgId.IsEmpty())
- dbei.szId = ft->m_szMsgId;
-
- auto *p = wcsrchr(ft->m_wszFileName, '\\');
- if (p == nullptr)
- p = ft->m_wszFileName;
- else
- p++;
- blob.setName(p);
-
- blob.setUrl(ft->m_szHost);
- blob.complete(ft->pfts.currentFileSize);
- blob.setLocalName(ft->m_wszFileName);
-}
-
-void CIcqProto::OnEventEdited(MCONTACT, MEVENT, const DBEVENTINFO &)
-{
-
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// batch events deletion from the server
-
-void CIcqProto::OnBatchDeleteMsg(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- RobustReply root(pReply);
- if (root.error() != 20000)
- return;
-
- if (auto *pUser = FindUser(GetUserId(pReq->hContact)))
- pUser->m_bSkipPatch = true;
- RetrievePatches(pReq->hContact);
-}
-
-void CIcqProto::BatchDeleteMsg()
-{
- JSONNode ids(JSON_ARRAY); ids.set_name("msgIds");
-
- mir_cslock lck(m_csDeleteQueue);
- for (auto &it : m_arDeleteQueue) {
- ids.push_back(JSONNode("", _atoi64(it)));
- mir_free(it);
- }
-
- auto *pReq = new AsyncRapiRequest(this, "delMsgBatch", &CIcqProto::OnBatchDeleteMsg);
- pReq->hContact = m_hDeleteContact;
- pReq->params << WCHAR_PARAM("sn", GetUserId(m_hDeleteContact)) << BOOL_PARAM("silent", true) << BOOL_PARAM("shared", m_bRemoveForAll) << ids;
- Push(pReq);
-
- m_arDeleteQueue.destroy();
- m_hDeleteContact = INVALID_CONTACT_ID;
-}
-
-void CIcqProto::OnEventDeleted(MCONTACT hContact, MEVENT hEvent, int flags)
-{
- // the command arrived from the server, don't send it back then
- if (!(flags & CDF_DEL_HISTORY))
- return;
-
- if (m_hDeleteContact != INVALID_CONTACT_ID)
- if (m_hDeleteContact != hContact)
- BatchDeleteMsg();
-
- DB::EventInfo dbei(hEvent, false);
- if (!dbei || !dbei.szId)
- return;
-
- mir_cslock lck(m_csDeleteQueue);
- m_hDeleteContact = hContact;
- m_bRemoveForAll = (flags & CDF_FOR_EVERYONE) != 0;
- m_arDeleteQueue.insert(mir_strdup(dbei.szId));
- m_impl.m_delete.Start(100);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static void __cdecl DownloadCallack(size_t iProgress, void *pParam)
-{
- auto *ofd = (OFDTHREAD *)pParam;
-
- DBVARIANT dbv = { DBVT_DWORD };
- dbv.dVal = unsigned(iProgress);
- db_event_setJson(ofd->hDbEvent, "ft", &dbv);
-}
-
-void __cdecl CIcqProto::OfflineFileThread(void *pParam)
-{
- auto *ofd = (OFDTHREAD *)pParam;
-
- DB::EventInfo dbei(ofd->hDbEvent);
- if (m_bOnline && dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) {
- DB::FILE_BLOB blob(dbei);
-
- CMStringW wszUrl;
- if (fileText2url(blob.getUrl(), &wszUrl)) {
- if (auto *pFileInfo = RetrieveFileInfo(dbei.hContact, wszUrl)) {
- if (!ofd->bCopy) {
- MHttpRequest nlhr(REQUEST_GET);
- nlhr.m_szUrl = pFileInfo->szUrl;
- nlhr.AddHeader("Sec-Fetch-User", "?1");
- nlhr.AddHeader("Sec-Fetch-Site", "cross-site");
- nlhr.AddHeader("Sec-Fetch-Mode", "navigate");
- nlhr.AddHeader("Accept-Encoding", "gzip");
-
- debugLogW(L"Saving to [%s]", ofd->wszPath.c_str());
- NLHR_PTR reply(Netlib_DownloadFile(m_hNetlibUser, &nlhr, ofd->wszPath, DownloadCallack, ofd));
- if (reply && reply->resultCode == 200) {
- struct _stat st;
- _wstat(ofd->wszPath, &st);
-
- DBVARIANT dbv = { DBVT_DWORD };
- dbv.dVal = st.st_size;
- db_event_setJson(ofd->hDbEvent, "ft", &dbv);
-
- ofd->Finish();
- }
- }
- else {
- ofd->wszPath.Empty();
- ofd->wszPath.Append(_A2T(pFileInfo->szUrl));
- ofd->pCallback->Invoke(*ofd);
- }
- }
- }
- }
-
- delete ofd;
-}
-
-INT_PTR __cdecl CIcqProto::SvcOfflineFile(WPARAM param, LPARAM)
-{
- ForkThread((MyThreadFunc)&CIcqProto::OfflineFileThread, (void *)param);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR CIcqProto::SvcLoadHistory(WPARAM hContact, LPARAM)
-{
- delSetting(hContact, DB_KEY_LASTMSGID);
-
- RetrieveUserHistory(hContact, 1, true);
- return 0;
-}
-
-INT_PTR CIcqProto::SvcEmptyHistory(WPARAM hContact, LPARAM)
-{
- auto *pReq = new AsyncRapiRequest(this, "delHistory");
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- pReq->hContact = hContact;
- pReq->params << WCHAR_PARAM("sn", GetUserId(hContact)) << INT64_PARAM("uptoMsgId", getId(hContact, DB_KEY_LASTMSGID));
- Push(pReq);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnBuildProtoMenu()
-{
- CMenuItem mi(&g_plugin);
- mi.root = Menu_GetProtocolRoot(this);
- mi.flags = CMIF_UNMOVABLE;
-
- // Groups uploader
- mi.pszService = "/UploadGroups";
- CreateProtoService(mi.pszService, &CIcqProto::UploadGroups);
- mi.name.a = LPGEN("Synchronize server groups");
- mi.position = 200001;
- mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_GROUP);
- m_hUploadGroups = Menu_AddProtoMenuItem(&mi, m_szModuleName);
-
- Menu_ShowItem(m_hUploadGroups, false);
-
- // Groups editor
- mi.pszService = "/EditGroups";
- CreateProtoService(mi.pszService, &CIcqProto::EditGroups);
- mi.name.a = LPGEN("Edit server groups");
- mi.position = 200002;
- mi.hIcolibItem = Skin_GetIconHandle(SKINICON_OTHER_GROUP);
- Menu_AddProtoMenuItem(&mi, m_szModuleName);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR CIcqProto::SvcGetEmailCount(WPARAM, LPARAM)
-{
- if (!m_bOnline)
- return 0;
- return m_unreadEmails;
-}
-
-INT_PTR CIcqProto::SvcGotoInbox(WPARAM, LPARAM)
-{
- Utils_OpenUrl("https://e.mail.ru/messages/inbox");
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// mark events read at the server
-
-void CIcqProto::SendMarkRead()
-{
- mir_cslock lck(m_csMarkReadQueue);
- while (m_arMarkReadQueue.getCount()) {
- auto *pUser = m_arMarkReadQueue[0];
-
- auto *pReq = new AsyncRapiRequest(this, "setDlgStateWim");
- pReq->params << WCHAR_PARAM("sn", GetUserId(pUser->m_hContact)) << INT64_PARAM("lastRead", getId(pUser->m_hContact, DB_KEY_LASTMSGID));
- Push(pReq);
-
- m_arMarkReadQueue.remove(0);
- }
-}
-
-void CIcqProto::OnMarkRead(MCONTACT hContact, MEVENT)
-{
- if (!m_bOnline)
- return;
-
- m_impl.m_markRead.Start(200);
-
- auto *pUser = FindUser(GetUserId(hContact));
- if (pUser) {
- mir_cslock lck(m_csMarkReadQueue);
- if (m_arMarkReadQueue.indexOf(pUser) == -1)
- m_arMarkReadQueue.insert(pUser);
- }
-}
-
-int CIcqProto::OnGroupChange(WPARAM hContact, LPARAM lParam)
-{
- if (!m_bOnline)
- return 0;
-
- CLISTGROUPCHANGE *pParam = (CLISTGROUPCHANGE*)lParam;
- if (hContact == 0) { // whole group is changed
- if (pParam->pszOldName == nullptr) {
- for (auto &it : m_arGroups)
- if (it->wszName == pParam->pszNewName)
- return 0;
-
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/addGroup")
- << AIMSID(this) << GROUP_PARAM("group", pParam->pszNewName));
- }
- else if (pParam->pszNewName == nullptr) {
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/removeGroup")
- << AIMSID(this) << GROUP_PARAM("group", pParam->pszOldName));
- }
- else {
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/renameGroup")
- << AIMSID(this) << GROUP_PARAM("oldGroup", pParam->pszOldName) << GROUP_PARAM("newGroup", pParam->pszNewName));
- }
- }
- else MoveContactToGroup(hContact, ptrW(getWStringA(hContact, "IcqGroup")), pParam->pszNewName);
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_AddToList - adds a contact to the contact list
-
-MCONTACT CIcqProto::AddToList(int, PROTOSEARCHRESULT *psr)
-{
- if (mir_wstrlen(psr->id.w) == 0)
- return 0;
-
- MCONTACT hContact = CreateContact(psr->id.w, true);
- if (psr->nick.w)
- setWString(hContact, "Nick", psr->nick.w);
- if (psr->firstName.w)
- setWString(hContact, "FirstName", psr->firstName.w);
- if (psr->lastName.w)
- setWString(hContact, "LastName", psr->lastName.w);
-
- return hContact;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PSR_AUTH
-
-int CIcqProto::AuthRecv(MCONTACT, DB::EventInfo &dbei)
-{
- return Proto_AuthRecv(m_szModuleName, dbei);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PSS_AUTHREQUEST
-
-int CIcqProto::AuthRequest(MCONTACT hContact, const wchar_t* szMessage)
-{
- ptrW wszGroup(Clist_GetGroup(hContact));
- if (!wszGroup)
- wszGroup = mir_wstrdup(L"General");
-
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_POST, "/buddylist/addBuddy", &CIcqProto::OnAddBuddy);
- pReq << AIMSID(this) << WCHAR_PARAM("authorizationMsg", szMessage) << WCHAR_PARAM("buddy", GetUserId(hContact)) << WCHAR_PARAM("group", wszGroup) << INT_PARAM("preAuthorized", 1);
- pReq->hContact = hContact;
- Push(pReq);
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// GetCaps - return protocol capabilities bits
-
-INT_PTR CIcqProto::GetCaps(int type, MCONTACT)
-{
- INT_PTR nReturn = 0;
-
- switch (type) {
- case PFLAGNUM_1:
- nReturn = PF1_IM | PF1_AUTHREQ | PF1_BASICSEARCH | PF1_ADDSEARCHRES | /*PF1_SEARCHBYNAME | TODO */
- PF1_FILE | PF1_CONTACT | PF1_SERVERCLIST;
- break;
-
- case PFLAGNUM_2:
- case PFLAGNUM_3:
- return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_INVISIBLE;
-
- case PFLAGNUM_5:
- return PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND;
-
- case PFLAGNUM_4:
- nReturn = PF4_FORCEAUTH | PF4_SUPPORTIDLE | PF4_OFFLINEFILES | PF4_IMSENDOFFLINE | PF4_SUPPORTTYPING |
- PF4_AVATARS | PF4_SERVERMSGID | PF4_READNOTIFY | PF4_REPLY;
- break;
-
- case PFLAG_UNIQUEIDTEXT:
- return (INT_PTR)TranslateT("E-mail");
- }
-
- return nReturn;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// GetInfo - retrieves a contact info
-
-int CIcqProto::GetInfo(MCONTACT hContact, int)
-{
- RetrieveUserInfo(hContact);
- RetrievePresence(hContact);
-
- if (Contact::IsGroupChat(hContact))
- RetrieveChatInfo(hContact);
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SearchBasic - searches the contact by UID
-
-HANDLE CIcqProto::SearchBasic(const wchar_t *pszSearch)
-{
- if (!m_bOnline)
- return nullptr;
-
- auto *pReq = new AsyncRapiRequest(this, "search", &CIcqProto::OnSearchResults);
- pReq->params << WCHAR_PARAM(*pszSearch == '+' ? "phonenum" : "keyword", pszSearch);
- Push(pReq);
-
- return pReq;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// SendFile - sends a file
-
-HANDLE CIcqProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles)
-{
- IcqFileTransfer *pTransfer = nullptr;
-
- for (int i = 0; ppszFiles[i] != 0; i++) {
- auto *pwszFileName = ppszFiles[i];
- struct _stat statbuf;
- if (_wstat(pwszFileName, &statbuf)) {
- debugLogW(L"'%s' is an invalid filename", pwszFileName);
- continue;
- }
-
- int iFileId = _wopen(pwszFileName, _O_RDONLY | _O_BINARY, _S_IREAD);
- if (iFileId < 0)
- continue;
-
- pTransfer = new IcqFileTransfer(hContact, pwszFileName);
- pTransfer->pfts.totalFiles = 1;
- pTransfer->pfts.currentFileSize = pTransfer->pfts.totalBytes = statbuf.st_size;
- pTransfer->m_fileId = iFileId;
- if (mir_wstrlen(szDescription))
- pTransfer->m_wszDescr = szDescription;
-
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, "https://files.icq.com/files/init", &CIcqProto::OnFileInit);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("f", "json") << WCHAR_PARAM("filename", pTransfer->m_wszShortName)
- << CHAR_PARAM("k", APP_ID) << INT_PARAM("size", statbuf.st_size) << INT_PARAM("ts", TS());
- CalcHash(pReq);
- pReq->pUserInfo = pTransfer;
- Push(pReq);
- }
-
- return pTransfer; // Success, if at least one file was sent
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SendMessage - sends a message
-
-int CIcqProto::SendMsg(MCONTACT hContact, MEVENT hReplyEvent, const char *pszSrc)
-{
- JSONNode parts(JSON_ARRAY);
- if (hReplyEvent) {
- DB::EventInfo dbei(hReplyEvent);
- if (dbei) {
- JSONNode replyTo;
- CMStringA replyId(GetUserId(dbei.hContact));
- replyTo << CHAR_PARAM("mediaType", "quote") << CHAR_PARAM("sn", replyId) << INT_PARAM("time", dbei.timestamp)
- << CHAR_PARAM("msgId", dbei.szId) << WCHAR_PARAM("friendly", Clist_GetContactDisplayName(dbei.hContact, 0))
- << WCHAR_PARAM("text", ptrW(dbei.getText()));
- parts.push_back(replyTo);
- }
- }
-
- JSONNode msgText; msgText << CHAR_PARAM("mediaType", "text") << CHAR_PARAM("text", pszSrc);
- parts.push_back(msgText);
-
- int id = InterlockedIncrement(&m_msgId);
- auto *pOwn = new IcqOwnMessage(hContact, id, pszSrc);
- {
- mir_cslock lck(m_csOwnIds);
- m_arOwnIds.insert(pOwn);
- }
-
- SendMessageParts(hContact, parts, pOwn);
- return id;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_SetStatus - sets the protocol status
-
-int CIcqProto::SetStatus(int iNewStatus)
-{
- debugLogA("CIcqProto::SetStatus iNewStatus = %d, m_iStatus = %d, m_iDesiredStatus = %d m_hWorkerThread = %p", iNewStatus, m_iStatus, m_iDesiredStatus, m_hWorkerThread);
-
- switch (iNewStatus) {
- case ID_STATUS_OFFLINE:
- case ID_STATUS_ONLINE:
- case ID_STATUS_INVISIBLE:
- break;
-
- default:
- iNewStatus = ID_STATUS_ONLINE;
- }
-
- if (iNewStatus == m_iStatus)
- return 0;
-
- int iOldStatus = m_iStatus;
-
- // go offline
- if (iNewStatus == ID_STATUS_OFFLINE) {
- if (m_bOnline)
- SetServerStatus(ID_STATUS_OFFLINE);
-
- m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
- setAllContactStatuses(ID_STATUS_OFFLINE, false);
-
- ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus);
- return 0;
- }
-
- m_iDesiredStatus = iNewStatus;
-
- // not logged in? come on
- if (!m_bOnline && !IsStatusConnecting(m_iStatus)) {
- m_iStatus = ID_STATUS_CONNECTING;
- ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus);
-
- if (mir_wstrlen(m_szOwnId) == 0) {
- debugLogA("Thread ended, UIN/password are not configured");
- ConnectionFailed(LOGINERR_BADUSERID);
- return 0;
- }
-
- if (!RetrievePassword()) {
- debugLogA("Thread ended, password is not configured");
- ConnectionFailed(LOGINERR_BADUSERID);
- return 0;
- }
-
- CheckPassword();
- }
- else if (m_bOnline) {
- debugLogA("setting server online status to %d", iNewStatus);
- SetServerStatus(iNewStatus);
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// PS_UserIsTyping - sends a UTN notification
-
-int CIcqProto::UserIsTyping(MCONTACT hContact, int type)
-{
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/im/setTyping")
- << AIMSID(this) << WCHAR_PARAM("t", GetUserId(hContact)) << CHAR_PARAM("typingStatus", (type == PROTOTYPE_SELFTYPING_ON) ? "typing" : "typed"));
- return 0;
-}
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h deleted file mode 100644 index 778a8a5236..0000000000 --- a/protocols/ICQ-WIM/src/proto.h +++ /dev/null @@ -1,499 +0,0 @@ -// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera, George Hazan
-// Copyright © 2012-2024 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Protocol Interface declarations
-// -----------------------------------------------------------------------------
-
-#ifndef _ICQ_PROTO_H_
-#define _ICQ_PROTO_H_
-
-#include "m_system.h"
-#include "m_protoint.h"
-
-#define APP_ID "ic1pzYNtEU6dDnEQ"
-
-#define ICQ_FILE_SERVER "https://u.icq.net/files/api/v1.1"
-#define ICQ_FAKE_EVENT_ID 0xBABAEB
-#define ICQ_ROBUST_SERVER "https://u.icq.net/rapi"
-#define ICQ_ROBUST_SERVER_NEW "https://u.icq.net/api/v92/rapi"
-
-#define PS_DUMMY "/DoNothing"
-#define PS_GOTO_INBOX "/SvcGotoInbox"
-
-#define WIM_CAP_VOIP_VOICE "094613504c7f11d18222444553540000"
-#define WIM_CAP_VOIP_VIDEO "094613514c7f11d18222444553540000"
-#define WIM_CAP_FILETRANSFER "094613434c7f11d18222444553540000"
-#define WIM_CAP_UNIQ_REQ_ID "094613534c7f11d18222444553540000"
-#define WIM_CAP_EMOJI "094613544c7f11d18222444553540000"
-#define WIM_CAP_MENTIONS "0946135b4c7f11d18222444553540000"
-#define WIM_CAP_MAIL_NOTIFICATIONS "094613594c7f11d18222444553540000"
-#define WIM_CAP_INTRO_DLG_STATE "0946135a4c7f11d18222444553540000"
-
-#define NG_CAP_SECUREIM "4d69724e47536563757265494d000000"
-
-typedef CProtoDlgBase<CIcqProto> CIcqDlgBase;
-
-struct AIMSID
-{
- AIMSID(CIcqProto *_ppro) :
- m_ppro(_ppro)
- {}
-
- CIcqProto *m_ppro;
-};
-
-enum ChatMenuItems
-{
- IDM_INVITE = 10, IDM_LEAVE
-};
-
-struct IcqFileInfo
-{
- IcqFileInfo(const std::string &pszUrl, const CMStringW &pwszDescr, uint32_t dwSize) :
- szUrl(pszUrl.c_str()),
- wszDescr(pwszDescr),
- dwFileSize(dwSize)
- {}
-
- CMStringA szUrl, szOrigUrl;
- CMStringW wszDescr;
- uint32_t dwFileSize;
- bool bIsSticker = false;
-};
-
-struct IcqGroup
-{
- IcqGroup(int _p1, const CMStringW &_p2) :
- id(_p1),
- wszSrvName(_p2)
- {
- SetName(_p2);
- }
-
- int id;
- int level;
- CMStringW wszName, wszSrvName;
-
- void SetName(const CMStringW &str)
- {
- wszName = str;
- level = wszName.SpanIncluding(L">").GetLength();
- if (level != 0)
- wszName.Delete(0, level);
- wszName.Replace(L">", L"\\");
- }
-};
-
-struct IcqUser : public MZeroedObject
-{
- IcqUser(const CMStringW &wszId, MCONTACT _contact) :
- m_aimid(wszId),
- m_hContact(_contact)
- {}
-
- CMStringW m_aimid;
- MCONTACT m_hContact;
- bool m_bInList, m_bGotCaps, m_bWasOnline, m_bSkipPatch;
- __int64 m_iProcessedMsgId;
- int m_iApparentMode;
- time_t m_timer1, m_timer2;
-};
-
-struct IcqConn
-{
- HNETLIBCONN s;
- int lastTs, timeout;
-};
-
-struct IcqFileTransfer : public MZeroedObject
-{
- bool m_bCanceled = false, m_bStarted = false;
- int m_fileId = -1;
- CMStringA m_szHost, m_szMsgId;
- CMStringW m_wszFileName, m_wszDescr;
- const wchar_t *m_wszShortName;
- PROTOFILETRANSFERSTATUS pfts;
-
- // create an object for sending
- IcqFileTransfer(MCONTACT hContact, const wchar_t *pwszFileName);
-
- ~IcqFileTransfer();
-
- void FillHeaders(AsyncHttpRequest *pReq);
-};
-
-struct IcqOwnMessage
-{
- IcqOwnMessage(MCONTACT _hContact, int _msgid, const char *pszText) :
- m_msgid(_msgid),
- m_hContact(_hContact),
- m_szText(mir_strdup(pszText))
- {
- }
-
- void setGuid(const char *pszGuid)
- {
- strncpy_s(m_guid, pszGuid, _TRUNCATE);
- }
-
- MCONTACT m_hContact;
- int m_msgid;
- char m_guid[50];
- ptrA m_szText;
- IcqFileTransfer *pTransfer = nullptr;
-};
-
-class CIcqProto : public PROTO<CIcqProto>
-{
- friend class CForwardDlg;
- friend struct AsyncRapiRequest;
-
- class CIcqProtoImpl
- {
- friend class CIcqProto;
-
- CIcqProto &m_proto;
- CTimer m_heartBeat, m_markRead, m_delete;
-
- void OnHeartBeat(CTimer *) {
- m_proto.CheckStatus();
- }
-
- void OnMarkRead(CTimer *pTimer) {
- m_proto.SendMarkRead();
- pTimer->Stop();
- }
-
- void OnDelete(CTimer *pTimer) {
- m_proto.BatchDeleteMsg();
- pTimer->Stop();
- }
-
- CIcqProtoImpl(CIcqProto &pro) :
- m_proto(pro),
- m_delete(Miranda_GetSystemWindow(), UINT_PTR(this)),
- m_markRead(Miranda_GetSystemWindow(), UINT_PTR(this) + 1),
- m_heartBeat(Miranda_GetSystemWindow(), UINT_PTR(this) + 2)
- {
- m_delete.OnEvent = Callback(this, &CIcqProtoImpl::OnDelete);
- m_markRead.OnEvent = Callback(this, &CIcqProtoImpl::OnMarkRead);
- m_heartBeat.OnEvent = Callback(this, &CIcqProtoImpl::OnHeartBeat);
- }
- } m_impl;
-
- friend struct CIcqRegistrationDlg;
- friend class CGroupchatInviteDlg;
- friend class CEditIgnoreListDlg;
- friend class COptionsDlg;
- friend class CIcqEnterLoginDlg;
- friend class CGroupEditDlg;
-
- friend AsyncHttpRequest* operator <<(AsyncHttpRequest*, const AIMSID&);
-
- bool m_bOnline, m_bTerminated, m_bFirstBos, m_bError462, m_bInvisible, m_bRemoveForAll;
- int m_iTimeShift;
-
- MCONTACT CheckOwnMessage(const CMStringA &reqId, const CMStringA &msgId, bool bRemove);
- void CheckPassword(void);
- void ConnectionFailed(int iReason, int iErrorCode = 0);
- void EmailNotification(const wchar_t *pwszText);
- void ForwardMessage(MEVENT hEVent, MCONTACT hContact);
- void GetPermitDeny();
- wchar_t* GetUIN(MCONTACT hContact);
- void MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup, const wchar_t *pwszNewGroup);
- void RetrieveHistoryChunk(MCONTACT hContact, __int64 patchVer, __int64 startMsgId, unsigned iCount);
- bool RetrievePassword();
- void RetrievePresence(MCONTACT hContact);
- void RetrieveUserCaps(IcqUser *pUser);
- void RetrieveUserHistory(MCONTACT, __int64 startMsgId, bool bCreateRead);
- void RetrieveUserInfo(MCONTACT hContact);
- void SendMrimLogin(MHttpResponse *pReply);
- void SendMessageParts(MCONTACT hContact, const JSONNode &parts, IcqOwnMessage *pOwn = nullptr);
- void SetOwnId(const CMStringW &wszId);
- void SetServerStatus(int iNewStatus);
- void ShutdownSession(void);
- void StartSession(void);
-
- void CheckAvatarChange(MCONTACT hContact, const JSONNode&);
- bool CheckFile(MCONTACT hContact, CMStringW &wszFileName, IcqFileInfo* &pFileInfo);
- void CheckLastId(MCONTACT hContact, const JSONNode&);
- void Json2int(MCONTACT, const JSONNode&, const char *szJson, const char *szSetting, bool bIsPartial);
- void Json2string(MCONTACT, const JSONNode&, const char *szJson, const char *szSetting, bool bIsPartial);
- MCONTACT ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact = INVALID_CONTACT_ID, bool bIsPartial = false);
- void ParseMessagePart(MCONTACT hContact, const JSONNode &msg, IcqFileInfo *&pFileInfo);
- IcqFileInfo* RetrieveFileInfo(MCONTACT hContact, const CMStringW &wszUrl);
- void RetrievePatches(MCONTACT hContact);
- int StatusFromPresence(const JSONNode &presence, MCONTACT hContact);
- void ProcessPatchVersion(MCONTACT hContact, __int64 currPatch);
- void ProcessStatus(IcqUser *pUser, int iStatus);
-
- enum PM {
- CreateRead = 1,
- LocalTime = 2,
- FetchFiles = 4
- };
- void ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNode &msg, int flags);
-
- void OnLoggedIn(void);
- void OnLoggedOut(void);
-
- mir_cs m_csMarkReadQueue;
- LIST<IcqUser> m_arMarkReadQueue;
- void SendMarkRead();
-
- mir_cs m_csDeleteQueue;
- LIST<char> m_arDeleteQueue;
- MCONTACT m_hDeleteContact = INVALID_CONTACT_ID;
- void BatchDeleteMsg();
-
- __int64 getId(MCONTACT hContact, const char *szSetting);
- void setId(MCONTACT hContact, const char *szSetting, __int64 iValue);
-
- void OnAddBuddy(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnAddClient(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnBatchDeleteMsg(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnCheckMraAuth(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnCheckMraAuthFinal(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnCheckMrimLogin(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnCheckPassword(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnCheckPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnFetchEvents(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnFileContinue(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnFileInit(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnFileInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGenToken(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetChatInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetPatches(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetPermitDeny(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGePresence(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetSticker(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetUserCaps(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetUserHistory(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnGetUserInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnLeaveChat(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnLoginViaPhone(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnNormalizePhone(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnReceiveAvatar(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnSearchResults(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnSendMessage(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnSessionEnd(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnStartSession(MHttpResponse *pReply, AsyncHttpRequest *pReq);
- void OnValidateSms(MHttpResponse *pReply, AsyncHttpRequest *pReq);
-
- void ProcessBuddyList(const JSONNode &pRoot);
- void ProcessDiff(const JSONNode &pRoot);
- void ProcessEvent(const JSONNode &pRoot);
- void ProcessGroupChat(const JSONNode &pRoot);
- void ProcessHistData(const JSONNode &pRoot);
- void ProcessImState(const JSONNode &pRoot);
- void ProcessMyInfo(const JSONNode &pRoot);
- void ProcessNotification(const JSONNode &pRoot);
- void ProcessOnline(const JSONNode &presence, MCONTACT hContact);
- void ProcessPermissions(const JSONNode &pRoot);
- void ProcessPresence(const JSONNode &pRoot);
- void ProcessSessionEnd(const JSONNode &pRoot);
- void ProcessTyping(const JSONNode &pRoot);
-
- IcqConn m_ConnPool[CONN_LAST];
- CMStringA m_szPassword;
- CMStringA m_szSessionKey;
- CMStringA m_szAToken;
- CMStringA m_szRToken;
- CMStringA m_fetchBaseURL;
- CMStringA m_aimsid;
- CMStringA m_szMraCookie;
- LONG m_msgId = 1;
- int m_iRClientId;
- HGENMENU m_hUploadGroups;
- MCONTACT m_hFavContact = INVALID_CONTACT_ID;
-
- mir_cs m_csOwnIds;
- OBJLIST<IcqOwnMessage> m_arOwnIds;
-
- OBJLIST<IcqGroup> m_arGroups;
-
- int m_unreadEmails = -1;
- CMStringA m_szMailBox;
-
- bool m_bIgnoreListEmpty = true;
- bool m_bRememberPwd; // store password in a database
- bool m_bDlgActive;
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // group chats
-
- int __cdecl GcEventHook(WPARAM, LPARAM);
- int __cdecl GcMenuHook(WPARAM, LPARAM);
-
- void GcProcessLogMenu(SESSION_INFO *si, int);
- void GcSendPrivateMessage(GCHOOK *gch);
-
- SESSION_INFO* GcCreate(const wchar_t *pwszId, const wchar_t *pwszNick);
-
- void RetrieveChatInfo(MCONTACT hContact);
-
- void InviteUserToChat(SESSION_INFO *si);
- void LeaveDestroyChat(SESSION_INFO *si);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // http queue
-
- mir_cs m_csHttpQueue;
- HANDLE m_evRequestsQueue;
- LIST<AsyncHttpRequest> m_arHttpQueue;
-
- void CalcHash(AsyncHttpRequest*);
- void DropQueue();
- bool ExecuteRequest(AsyncHttpRequest*);
- bool IsQueueEmpty();
- void Push(MHttpRequest*);
- bool RefreshRobustToken(AsyncHttpRequest *pReq);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // cache
-
- mir_cs m_csCache;
- OBJLIST<IcqUser> m_arCache;
-
- IcqUser* FindUser(const CMStringW &pwszId);
- MCONTACT CreateContact(const CMStringW &pwszId, bool bTemporary);
-
- void GetAvatarFileName(MCONTACT hContact, wchar_t *pszDest, size_t cbLen);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // Menus
-
- HGENMENU hmiForward, hmiConvert, hmiFavorites;
-
- void InitMenus();
-
- INT_PTR __cdecl SvcExecMenu(WPARAM, LPARAM);
- int __cdecl OnPrebuildMenu(WPARAM, LPARAM);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // threads
-
- HANDLE m_hWorkerThread;
- void __cdecl ServerThread(void*);
- void __cdecl PollThread(void*);
- void __cdecl OfflineFileThread(void*);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // services
-
- INT_PTR __cdecl GetAvatar(WPARAM, LPARAM);
- INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
- INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
- INT_PTR __cdecl SetAvatar(WPARAM, LPARAM);
-
- INT_PTR __cdecl SvcLeaveChat(WPARAM, LPARAM);
- INT_PTR __cdecl SvcOfflineFile(WPARAM, LPARAM);
-
- INT_PTR __cdecl EditGroups(WPARAM, LPARAM);
- INT_PTR __cdecl SvcGetEmailCount(WPARAM, LPARAM);
- INT_PTR __cdecl SvcGotoInbox(WPARAM, LPARAM);
- INT_PTR __cdecl UploadGroups(WPARAM, LPARAM);
-
- INT_PTR __cdecl SvcLoadHistory(WPARAM, LPARAM);
- INT_PTR __cdecl SvcEmptyHistory(WPARAM, LPARAM);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // events
-
- int __cdecl OnGroupChange(WPARAM, LPARAM);
- int __cdecl OnOptionsInit(WPARAM, LPARAM);
- int __cdecl OnUserInfoInit(WPARAM, LPARAM);
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // PROTO_INTERFACE
-
- MCONTACT AddToList( int flags, PROTOSEARCHRESULT *psr) override;
-
- int AuthRecv(MCONTACT, DB::EventInfo &dbei) override;
- int AuthRequest(MCONTACT hContact, const wchar_t *szMessage) override;
-
- INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
- int GetInfo(MCONTACT hContact, int infoType) override;
-
- HANDLE SearchBasic(const wchar_t *id) override;
-
- HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override;
- int SendMsg(MCONTACT hContact, MEVENT hReplyEvent, const char *msg) override;
-
- int SetStatus(int iNewStatus) override;
-
- int UserIsTyping(MCONTACT hContact, int type) override;
-
- void OnBuildProtoMenu(void) override;
- void OnCacheInit() override;
- void OnContactAdded(MCONTACT) override;
- bool OnContactDeleted(MCONTACT, uint32_t flags) override;
- MWindow OnCreateAccMgrUI(MWindow) override;
- void OnEventDeleted(MCONTACT, MEVENT, int) override;
- void OnEventEdited(MCONTACT, MEVENT, const DBEVENTINFO &dbei) override;
- void OnMarkRead(MCONTACT, MEVENT) override;
- void OnModulesLoaded() override;
- void OnReceiveOfflineFile(DB::FILE_BLOB &blob) override;
- void OnSendOfflineFile(DB::EventInfo &dbei, DB::FILE_BLOB &blob, void *ft) override;
- void OnShutdown() override;
-
-public:
- CIcqProto(const char*, const wchar_t*);
- ~CIcqProto();
-
- CMOption<wchar_t*> m_szOwnId; // our own aim id
-
- CMOption<bool> m_bHideGroupchats; // don't pop up group chat windows on startup
- CMOption<bool> m_bUseTrayIcon; // use tray icon notifications
- CMOption<bool> m_bErrorPopups; // display popups with errors
- CMOption<bool> m_bLaunchMailbox; // launch browser to view email
-
- CMOption<uint32_t> m_iTimeDiff1; // set this status to m_iStatus1 after this interval of secs
- CMOption<uint32_t> m_iStatus1;
- CMOption<uint32_t> m_iTimeDiff2; // set this status to m_iStatus2 after this interval of secs
- CMOption<uint32_t> m_iStatus2;
-
- void CheckStatus(void);
- void PatchProfileInfo(const char *pszVariable, const wchar_t *pwszValue);
-
- MCONTACT GetRealContact(IcqUser *pUser);
- CMStringW GetUserId(MCONTACT);
-
- __forceinline int TS() const
- { return time(0) - m_iTimeShift;
- }
-
- void SetPermitDeny(const CMStringW &userId, bool bAllow);
-};
-
-struct CMPlugin : public ACCPROTOPLUGIN<CIcqProto>
-{
- CMPlugin();
-
- int Load() override;
-};
-
-#endif
diff --git a/protocols/ICQ-WIM/src/resource.h b/protocols/ICQ-WIM/src/resource.h deleted file mode 100644 index caf5010db6..0000000000 --- a/protocols/ICQ-WIM/src/resource.h +++ /dev/null @@ -1,58 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by W:\miranda-ng\protocols\ICQ-WIM\res\resources.rc -// -#define IDD_OPTIONS_FULL 101 -#define IDD_OPTIONS_ACCMGR 102 -#define IDD_GROUPCHAT_INVITE 103 -#define IDD_INFO_ICQ 104 -#define IDD_REGISTER 105 -#define IDD_EDITIGNORE 106 -#define IDI_INBOX 107 -#define IDI_MAIL_NOTIFY 108 -#define IDD_OPTIONS_ADV 109 -#define IDD_LOGINPW 110 -#define IDD_EDITGROUPS 111 -#define IDD_FORWARD 112 -#define IDI_FORWARD 113 -#define IDD_ABOUT 114 -#define IDC_PASSWORD 1001 -#define IDC_UIN 1002 -#define IDC_UIN2 1003 -#define IDC_HIDECHATS 1004 -#define IDC_REGISTER 1005 -#define IDC_PHONE 1006 -#define IDC_CLIST 1007 -#define IDC_SENDSMS 1008 -#define IDC_CODE 1009 -#define IDC_ONLINESINCE 1010 -#define IDC_ABOUT 1011 -#define IDC_NICK 1012 -#define IDC_FIRST_NAME 1013 -#define IDC_LASTSEEN 1014 -#define IDC_SAVEPASS 1015 -#define IDC_MEMBERSINCE2 1015 -#define IDC_LIST 1016 -#define IDC_LAST_NAME 1016 -#define IDC_DIFF1 1017 -#define IDC_SPIN1 1018 -#define IDC_STATUS1 1019 -#define IDC_USETRAYICON 1020 -#define IDC_LAUNCH_MAILBOX 1021 -#define IDC_SHOWERRORPOPUPS 1022 -#define IDC_DIFF2 1023 -#define IDC_SPIN2 1024 -#define IDC_STATUS2 1025 -#define IDC_GROUPS 1025 -#define IDC_UIN_LABEL 1026 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 114 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1026 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp deleted file mode 100644 index 7f0441df45..0000000000 --- a/protocols/ICQ-WIM/src/server.cpp +++ /dev/null @@ -1,1519 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#pragma comment(lib, "libcrypto.lib")
-
-void CIcqProto::CheckAvatarChange(MCONTACT hContact, const JSONNode &ev)
-{
- CMStringW wszIconId(ev["bigIconId"].as_mstring());
- if (wszIconId.IsEmpty())
- wszIconId = ev["iconId"].as_mstring();
- if (wszIconId.IsEmpty())
- wszIconId = ev["avatarId"].as_mstring();
-
- if (!wszIconId.IsEmpty()) {
- CMStringW oldIconID(getMStringW(hContact, "IconId"));
- if (wszIconId == oldIconID) {
- wchar_t wszFullName[MAX_PATH];
- GetAvatarFileName(hContact, wszFullName, _countof(wszFullName));
- if (_waccess(wszFullName, 0) == 0)
- return;
- }
-
- setWString(hContact, "IconId", wszIconId);
-
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/expressions/get", &CIcqProto::OnReceiveAvatar);
- pReq << CHAR_PARAM("f", "native") << WCHAR_PARAM("t", GetUserId(hContact)) << CHAR_PARAM("type", "bigBuddyIcon");
- pReq->hContact = hContact;
- Push(pReq);
- }
- else delSetting(hContact, "IconId");
-}
-
-void CIcqProto::CheckLastId(MCONTACT hContact, const JSONNode &ev)
-{
- __int64 msgId = _wtoi64(ev["histMsgId"].as_mstring());
- __int64 lastId = getId(hContact, DB_KEY_LASTMSGID);
- if (msgId > lastId)
- setId(hContact, DB_KEY_LASTMSGID, msgId);
-}
-
-MCONTACT CIcqProto::CheckOwnMessage(const CMStringA &reqId, const CMStringA &msgId, bool bRemove)
-{
- IcqOwnMessage *pOwn = nullptr;
- {
- mir_cslock lck(m_csOwnIds);
- for (auto &it : m_arOwnIds) {
- if (reqId == it->m_guid) {
- pOwn = it;
- break;
- }
- }
- }
-
- if (pOwn == nullptr)
- return 0;
-
- MCONTACT ret = pOwn->m_hContact;
-
- if (pOwn->pTransfer) {
- if (bRemove) {
- pOwn->pTransfer->m_szMsgId = msgId;
- ProtoBroadcastAck(pOwn->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, pOwn->pTransfer);
- delete pOwn->pTransfer;
- }
- }
- else if (!Contact::IsGroupChat(ret))
- ProtoBroadcastAck(ret, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)pOwn->m_msgid, (LPARAM)msgId.c_str());
- else {
- T2Utf szOwnId(m_szOwnId);
-
- DB::EventInfo dbei;
- dbei.szId = msgId.c_str();
- dbei.timestamp = time(0);
- dbei.pBlob = pOwn->m_szText;
- dbei.flags = DBEF_SENT | DBEF_READ;
- dbei.szUserId = szOwnId;
- ProtoChainRecvMsg(pOwn->m_hContact, dbei);
- }
-
- if (auto hDbEvent = db_event_getById(m_szModuleName, msgId))
- db_event_delivered(pOwn->m_hContact, hDbEvent);
-
- if (bRemove) {
- mir_cslock lck(m_csOwnIds);
- m_arOwnIds.remove(pOwn);
- }
- return ret;
-}
-
-void CIcqProto::CheckPassword()
-{
- char mirVer[100];
- Miranda_GetVersionText(mirVer, _countof(mirVer));
-
- m_szAToken = getMStringA(DB_KEY_ATOKEN);
- m_iRClientId = getDword(DB_KEY_RCLIENTID);
- m_szSessionKey = getMStringA(DB_KEY_SESSIONKEY);
- if (!m_szAToken.IsEmpty() && !m_szSessionKey.IsEmpty()) {
- StartSession();
- return;
- }
-
- m_bError462 = false;
- SendMrimLogin(nullptr);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnFileInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- IcqFileInfo **res = (IcqFileInfo **)pReq->pUserInfo;
- *res = nullptr;
-
- RobustReply root(pReply);
- if (root.error() != 200)
- return;
-
- auto &pData = root.result();
- auto &pInfo = pData["info"];
- std::string szUrl(pInfo["dlink"].as_string());
- if (szUrl.empty())
- return;
-
- OnMarkRead(pReq->hContact, 0);
-
- mir_urlDecode(&*szUrl.begin());
-
- CMStringW wszDescr(pInfo["file_name"].as_mstring());
- *res = new IcqFileInfo(szUrl, wszDescr, pInfo["file_size"].as_int());
-}
-
-IcqFileInfo *CIcqProto::RetrieveFileInfo(MCONTACT hContact, const CMStringW &wszUrl)
-{
- IcqFileInfo *pFileInfo = nullptr;
- CMStringA szUrl(FORMAT, ICQ_FILE_SERVER "/info/%S/", wszUrl.c_str());
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnFileInfo);
- pReq->hContact = hContact;
- pReq->pUserInfo = &pFileInfo;
- pReq << CHAR_PARAM("aimsid", m_aimsid) << CHAR_PARAM("previews", "192,600,xlarge");
- if (!ExecuteRequest(pReq))
- return nullptr;
-
- return pFileInfo;
-}
-
-bool CIcqProto::CheckFile(MCONTACT hContact, CMStringW &wszText, IcqFileInfo *&pFileInfo)
-{
- CMStringW wszUrl;
- int idx = fileText2url(wszText, &wszUrl);
- if (!idx)
- return false;
-
- pFileInfo = nullptr;
-
- // download file info
- pFileInfo = RetrieveFileInfo(hContact, wszUrl);
- if (!pFileInfo)
- return false;
-
- if (idx != -1) {
- pFileInfo->szOrigUrl = wszText.Mid(0, idx);
- wszText.Delete(0, idx + 1);
- }
- else {
- pFileInfo->szOrigUrl = wszText;
- wszText.Empty();
- }
- return true;
-}
-
-void CIcqProto::CheckStatus()
-{
- time_t now = time(0);
- int diff1 = m_iTimeDiff1, diff2 = m_iTimeDiff2;
-
- for (auto &it : m_arCache) {
- // this contact is really offline and is on the first timer
- // if the first timer is expired, we clear it and look for the second status
- if (diff1 && it->m_timer1 && now - it->m_timer1 > diff1) {
- it->m_timer1 = 0;
-
- // if the second timer is set up, activate it
- if (m_iTimeDiff2) {
- setWord(it->m_hContact, "Status", m_iStatus2);
- it->m_timer2 = now;
- }
- // if the second timer is not set, simply mark a contact as offline
- else setWord(it->m_hContact, "Status", ID_STATUS_OFFLINE);
- continue;
- }
-
- // if the second timer is expired, set status to offline
- if (diff2 && it->m_timer2 && now - it->m_timer2 > m_iTimeDiff2) {
- it->m_timer2 = 0;
- setWord(it->m_hContact, "Status", ID_STATUS_OFFLINE);
- }
- }
-}
-
-void CIcqProto::ConnectionFailed(int iReason, int iErrorCode)
-{
- debugLogA("ConnectionFailed -> reason %d", iReason);
-
- if (m_bErrorPopups) {
- POPUPDATAW Popup = {};
- Popup.lchIcon = IcoLib_GetIconByHandle(Skin_GetIconHandle(SKINICON_ERROR), true);
- wcscpy_s(Popup.lpwzContactName, m_tszUserName);
- switch (iReason) {
- case LOGINERR_BADUSERID:
- mir_snwprintf(Popup.lpwzText, TranslateT("You have not entered a login or password.\nConfigure this in Options -> Network -> MRA and try again."));
- break;
- case LOGINERR_WRONGPASSWORD:
- mir_snwprintf(Popup.lpwzText, TranslateT("Connection failed.\nYour login or password was rejected (%d)."), iErrorCode);
- break;
- case LOGINERR_NONETWORK:
- case LOGINERR_NOSERVER:
- mir_snwprintf(Popup.lpwzText, TranslateT("Connection failed.\nThe server is temporarily unavailable (%d)."), iErrorCode);
- break;
- default:
- mir_snwprintf(Popup.lpwzText, TranslateT("Connection failed.\nUnknown error during sign on: %d"), iErrorCode);
- break;
- }
- PUAddPopupW(&Popup);
- }
-
- ProtoBroadcastAck(0, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, iReason);
- ShutdownSession();
-}
-
-void CIcqProto::MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup, const wchar_t *pwszNewGroup)
-{
- // otherwise we'll get a server error
- if (!mir_wstrlen(pwszGroup))
- return;
-
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/buddylist/moveBuddy") << AIMSID(this) << WCHAR_PARAM("buddy", GetUserId(hContact))
- << GROUP_PARAM("group", pwszGroup);
- if (mir_wstrlen(pwszNewGroup))
- pReq << GROUP_PARAM("newGroup", pwszNewGroup);
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnLoggedIn()
-{
- debugLogA("CIcqProto::OnLoggedIn");
- m_bOnline = true;
- m_impl.m_heartBeat.Start(1000);
-
- for (auto &it : m_arCache)
- it->m_timer1 = it->m_timer2 = 0;
-
- if (m_hFavContact != INVALID_CONTACT_ID)
- setWord(m_hFavContact, "Status", ID_STATUS_ONLINE);
-
- SetServerStatus(m_iDesiredStatus);
- RetrieveUserInfo(0);
- GetPermitDeny();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnLoggedOut()
-{
- debugLogA("CIcqProto::OnLoggedOut");
- m_bOnline = false;
- m_impl.m_heartBeat.Stop();
-
- for (auto &it : m_arCache)
- it->m_timer1 = it->m_timer2 = 0;
-
- ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE);
- m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
-
- setAllContactStatuses(ID_STATUS_OFFLINE, false);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact, bool bIsPartial)
-{
- // user chat?
- CMStringW wszId(buddy["aimId"].as_mstring());
- if (IsChat(wszId)) {
- if (auto *pUser = FindUser(wszId))
- if (pUser->m_iApparentMode == ID_STATUS_OFFLINE)
- return INVALID_CONTACT_ID;
-
- CMStringW wszChatName(buddy["friendly"].as_mstring());
- auto *si = GcCreate(wszId, wszChatName);
- return (si) ? si->hContact : INVALID_CONTACT_ID;
- }
-
- bool bIgnored = !IsValidType(buddy);
- if (hContact == INVALID_CONTACT_ID) {
- if (bIgnored)
- return INVALID_CONTACT_ID;
-
- debugLogA("creating a user with id=%S", wszId.c_str());
- hContact = CreateContact(wszId, false);
- if (auto *pUser = FindUser(wszId))
- pUser->m_bInList = true;
- }
- else if (bIgnored) {
- db_delete_contact(hContact, CDF_FROM_SERVER);
- return INVALID_CONTACT_ID;
- }
-
- CMStringA szVer;
- bool bVersionDetected = false, bSecureIM = false;
-
- for (auto &it : buddy["capabilities"]) {
- CMStringW wszCap(it.as_mstring());
- if (wszCap.GetLength() != 32)
- continue;
-
- uint8_t cap[16];
- hex2binW(wszCap, cap, sizeof(cap));
- if (!memcmp(cap, "MiNG", 4)) { // Miranda
- int v[4];
- if (4 == swscanf(wszCap.c_str() + 16, L"%04x%04x%04x%04x", &v[0], &v[1], &v[2], &v[3])) {
- szVer.Format("Miranda NG %d.%d.%d.%d (ICQ %d.%d.%d.%d)", v[0], v[1], v[2], v[3], cap[4], cap[5], cap[6], cap[7]);
- setString(hContact, "MirVer", szVer);
- bVersionDetected = true;
- }
- }
- else if (wszCap == _A2W(NG_CAP_SECUREIM)) {
- bSecureIM = bVersionDetected = true;
- }
- else if (!memcmp(cap, "Mod by Mikanoshi", 16)) {
- szVer = "R&Q build by Mikanoshi";
- bVersionDetected = true;
- }
- else if (!memcmp(cap, "Mandarin IM", 11)) {
- szVer = "Mandarin IM";
- bVersionDetected = true;
- }
- }
-
- if (bVersionDetected) {
- if (bSecureIM)
- szVer.Append(" + SecureIM");
- setString(hContact, "MirVer", szVer);
- }
- else delSetting(hContact, "MirVer");
-
- const JSONNode &var = buddy["friendly"];
- if (var && hContact != m_hFavContact)
- setWString(hContact, "Nick", var.as_mstring());
-
- if (buddy["deleted"].as_bool()) {
- setByte(hContact, "IcqDeleted", 1);
- Contact::PutOnList(hContact);
- }
-
- Json2string(hContact, buddy, "about", "About", bIsPartial);
- Json2string(hContact, buddy, "emailId", "Email", bIsPartial);
- Json2string(hContact, buddy, "cellNumber", "Cellular", bIsPartial);
- Json2string(hContact, buddy, "workNumber", "CompanyPhone", bIsPartial);
-
- // we shall not remove existing phone number anyhow
- Json2string(hContact, buddy, "phoneNumber", DB_KEY_PHONE, true);
-
- Json2int(hContact, buddy, "official", "Official", bIsPartial);
- Json2int(hContact, buddy, "idleTime", "IdleTS", bIsPartial);
-
- int iStatus = StatusFromPresence(buddy, hContact);
- if (iStatus > 0)
- setWord(hContact, "Status", iStatus);
-
- const JSONNode &profile = buddy["profile"];
- if (profile) {
- Json2string(hContact, profile, "friendlyName", DB_KEY_ICQNICK, bIsPartial);
- Json2string(hContact, profile, "firstName", "FirstName", bIsPartial);
- Json2string(hContact, profile, "lastName", "LastName", bIsPartial);
- Json2string(hContact, profile, "aboutMe", DB_KEY_ABOUT, bIsPartial);
-
- ptrW wszNick(getWStringA(hContact, "Nick"));
- if (!wszNick) {
- CMStringW srvNick = profile["friendlyName"].as_mstring();
- if (!srvNick.IsEmpty())
- setWString(hContact, "Nick", srvNick);
- }
-
- time_t birthDate = profile["birthDate"].as_int();
- if (birthDate != 0) {
- struct tm *timeinfo = localtime(&birthDate);
- if (timeinfo != nullptr) {
- setWord(hContact, "BirthDay", timeinfo->tm_mday);
- setWord(hContact, "BirthMonth", timeinfo->tm_mon+1);
- setWord(hContact, "BirthYear", timeinfo->tm_year+1900);
- }
- }
-
- CMStringW str = profile["gender"].as_mstring();
- if (!str.IsEmpty()) {
- if (str == "male")
- setByte(hContact, "Gender", 'M');
- else if (str == "female")
- setByte(hContact, "Gender", 'F');
- }
-
- for (auto &it : profile["homeAddress"]) {
- Json2string(hContact, it, "city", "City", bIsPartial);
- Json2string(hContact, it, "state", "State", bIsPartial);
- Json2string(hContact, it, "country", "Country", bIsPartial);
- }
- }
- else {
- Json2string(hContact, buddy, "firstName", "FirstName", bIsPartial);
- Json2string(hContact, buddy, "lastName", "LastName", bIsPartial);
- }
-
- CMStringW str = buddy["statusMsg"].as_mstring();
- if (str.IsEmpty())
- db_unset(hContact, "CList", "StatusMsg");
- else
- db_set_ws(hContact, "CList", "StatusMsg", str);
-
- CheckAvatarChange(hContact, buddy);
- return hContact;
-}
-
-void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNode &it, int flags)
-{
- CMStringA szMsgId(it["msgId"].as_mstring()), szSender, szReply;
- __int64 msgId = _atoi64(szMsgId);
- if (msgId > lastMsgId)
- lastMsgId = msgId;
-
- MEVENT hEvent = db_event_getById(m_szModuleName, szMsgId);
- bool bLocalTime = (flags & PM::LocalTime) != 0;
- int iMsgTime = (bLocalTime) ? time(0) : it["time"].as_int();
-
- if (auto &node = it["chat"]["sender"])
- szSender = node.as_mstring();
-
- CMStringW wszText = it["text"].as_mstring();
- wszText.TrimRight();
-
- if (it["hasAnimatedSticker"].as_bool()) {
- CMStringW wszUrl;
- if (fileText2url(wszText, &wszUrl)) {
- // is it already downloaded sticker?
- CMStringW wszLoadedPath(FORMAT, L"%s\\%S\\Stickers\\STK{%s}.png", VARSW(L"%miranda_avatarcache%").get(), m_szModuleName, wszUrl.c_str());
- if (_waccess(wszLoadedPath, 0)) {
- CMStringA szFullUrl("https://cicq.org/lottie_preview/stickerpicker_large/");
- szFullUrl += wszUrl;
- auto *pNew = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, szFullUrl, &CIcqProto::OnGetSticker);
- pNew->flags |= NLHRF_NODUMP | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
- pNew->pUserInfo = wszUrl.GetBuffer();
- pNew->AddHeader("Sec-Fetch-User", "?1");
- pNew->AddHeader("Sec-Fetch-Site", "cross-site");
- pNew->AddHeader("Sec-Fetch-Mode", "navigate");
- pNew->AddHeader("Accept-Encoding", "gzip");
- ExecuteRequest(pNew);
- }
- wszText.Format(L"STK{%s}", wszUrl.c_str());
- }
- }
- else {
- if (it["class"].as_mstring() == L"event") {
- CMStringW wszType(it["eventTypeId"].as_mstring());
-
- // user added you
- if (wszType == L"27:33000") {
- if (bLocalTime) {
- CMStringA id = getMStringA(hContact, DB_KEY_ID);
- int pos = id.Find('@');
- CMStringA nick = (pos == -1) ? id : id.Left(pos);
- DB::AUTH_BLOB blob(hContact, nick, nullptr, nullptr, id, nullptr);
-
- DB::EventInfo dbei;
- dbei.timestamp = (uint32_t)time(0);
- dbei.cbBlob = blob.size();
- dbei.pBlob = blob;
- ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&dbei);
- }
- return;
- }
-
- if (auto &pChat = it["chat"]) {
- auto *si = Chat_Find(pChat["sender"].as_mstring(), m_szModuleName);
- if (si == nullptr)
- return;
-
- if (pChat["type"].as_string() == "group") {
- if (pChat["memberEvent"]["type"].as_string() == "kicked") {
- GCEVENT gce = {};
- gce.si = si;
- gce.time = iMsgTime;
- gce.iType = GC_EVENT_KICK;
-
- for (auto &jt : pChat["memberEvent"]["members"]) {
- auto userId = jt.as_mstring();
- gce.pszUID.w = userId;
- Chat_Event(&gce);
- }
- }
- }
- return;
- }
-
- // message was deleted
- if (wszType == L"27:51000")
- wszText = TranslateT("Message was deleted");
- }
- }
-
- bool bIsOutgoing = it["outgoing"].as_bool();
- bool bIsChat = Contact::IsGroupChat(hContact);
-
- // check for embedded file
- IcqFileInfo *pFileInfo = nullptr;
- const JSONNode *pForward = nullptr, *pQuote = nullptr;
-
- for (auto &jt : it["parts"]) {
- auto szType = jt["mediaType"].as_string();
- if (szType == "forward")
- pForward = &jt;
- else if (szType == "quote")
- pQuote = &jt;
- else if (szType == "text")
- ParseMessagePart(hContact, jt, pFileInfo);
- }
-
- if (pForward) {
- int idx = wszText.Find(L"\n\n");
- if (idx != -1)
- wszText.Truncate(idx + 2);
-
- if (!pFileInfo) {
- ParseMessagePart(hContact, *pForward, pFileInfo);
- if (pFileInfo)
- pFileInfo->wszDescr = wszText;
- }
- }
-
- if (pQuote) {
- szReply = pQuote->at("msgId").as_mstring();
-
- if (!pFileInfo) {
- ParseMessagePart(hContact, *pQuote, pFileInfo);
- if (pFileInfo)
- pFileInfo->wszDescr = wszText;
- }
- }
-
- // message text might be a separate file link as well
- if (pFileInfo == nullptr && fileText2url(wszText)) {
- if (hEvent)
- return;
-
- CheckFile(hContact, wszText, pFileInfo);
- if (pFileInfo)
- pFileInfo->wszDescr = wszText;
- }
-
- // process our own messages
- bool bCreateRead = (flags & PM::CreateRead) != 0;
- CMStringA reqId(it["reqId"].as_mstring());
- if (CheckOwnMessage(reqId, szMsgId, true)) {
- debugLogA("Skipping our own message %s", szMsgId.c_str());
- if (!bIsChat) // prevent duplicates in private chats
- return;
- bIsOutgoing = bCreateRead = true;
- }
- else if (bIsChat)
- bCreateRead = true;
-
- // convert a file info into Miranda's file transfer
- if (pFileInfo) {
- auto *pszShortName = pFileInfo->szUrl.c_str();
- int slashPos = pFileInfo->szUrl.ReverseFind('/');
- if (slashPos != -1) {
- slashPos++;
- pszShortName += slashPos;
- }
-
- DB::EventInfo dbei(hEvent);
- dbei.eventType = EVENTTYPE_FILE;
- dbei.flags = DBEF_TEMPORARY;
- dbei.szId = szMsgId;
- dbei.timestamp = iMsgTime;
- if (bCreateRead)
- dbei.flags |= DBEF_READ;
- if (bIsOutgoing)
- dbei.flags |= DBEF_SENT;
- if (!szReply.IsEmpty())
- dbei.szReplyId = szReply;
- if (isChatRoom(hContact))
- dbei.szUserId = szSender;
-
- int iSaveSize = pFileInfo->dwFileSize;
- CMStringA szUrl(pFileInfo->szUrl);
-
- DB::FILE_BLOB blob(pFileInfo, pszShortName, T2Utf(pFileInfo->wszDescr));
- if (hEvent) {
- OnReceiveOfflineFile(blob);
- blob.write(dbei);
- db_event_edit(hEvent, &dbei, true);
- }
- else hEvent = ProtoChainRecvFile(hContact, blob, dbei);
-
- if (flags & PM::FetchFiles) {
- wchar_t wszReceiveFolder[MAX_PATH];
- File::GetReceivedFolder(hContact, wszReceiveFolder, _countof(wszReceiveFolder), true);
- CMStringW wszFileName(FORMAT, L"%s%s", wszReceiveFolder, blob.getName());
-
- // download & save file only if it's missing
- struct _stat st = {};
- int rc = _wstat(wszFileName, &st);
- if (rc != 0 || st.st_size != iSaveSize) {
- MHttpRequest nlhr(REQUEST_GET);
- nlhr.flags = NLHRF_REDIRECT;
- if (slashPos == -1)
- nlhr.m_szUrl = mir_urlEncode(szUrl);
- else
- nlhr.m_szUrl = szUrl.Mid(0, slashPos) + mir_urlEncode(szUrl.Mid(slashPos));
- nlhr.AddHeader("Sec-Fetch-User", "?1");
- nlhr.AddHeader("Sec-Fetch-Site", "cross-site");
- nlhr.AddHeader("Sec-Fetch-Mode", "navigate");
- nlhr.AddHeader("Accept-Encoding", "gzip");
-
- debugLogW(L"Saving to [%s]", wszFileName.c_str());
- NLHR_PTR reply(Netlib_DownloadFile(m_hNetlibUser, &nlhr, wszFileName.c_str(), 0, 0));
- if (!reply || reply->resultCode != 200)
- return;
- }
-
- blob.setLocalName(wszFileName);
- blob.complete(iSaveSize);
- blob.write(dbei);
- db_event_edit(hEvent, &dbei, true);
- }
-
- return;
- }
-
- // suppress notifications for already loaded/processed messages
- __int64 storedLastId = getId(hContact, DB_KEY_LASTMSGID);
- if (msgId <= storedLastId) {
- debugLogA("Parsing old/processed message with id %lld < %lld, setting CR to true", msgId, storedLastId);
- bCreateRead = true;
- }
-
- debugLogA("Adding message %d:%lld (CR=%d)", hContact, msgId, bCreateRead);
-
- ptrA szUtf(mir_utf8encodeW(wszText));
-
- DB::EventInfo dbei(hEvent);
- dbei.szModule = m_szModuleName;
- dbei.timestamp = iMsgTime;
- dbei.flags = DBEF_UTF;
- if (bIsOutgoing)
- dbei.flags |= DBEF_SENT;
- if (bCreateRead)
- dbei.flags |= DBEF_READ;
- dbei.cbBlob = (int)mir_strlen(szUtf);
- dbei.szId = szMsgId;
- if (isChatRoom(hContact))
- dbei.szUserId = szSender;
- if (!szReply.IsEmpty())
- dbei.szReplyId = szReply;
-
- if (dbei) {
- replaceStr(dbei.pBlob, szUtf.detach());
- db_event_edit(hEvent, &dbei, true);
- }
- else {
- dbei.pBlob = szUtf;
- ProtoChainRecvMsg(hContact, dbei);
- }
-}
-
-void CIcqProto::ParseMessagePart(MCONTACT hContact, const JSONNode &part, IcqFileInfo *&pFileInfo)
-{
- if (pFileInfo != nullptr)
- return;
-
- if (auto &content = part["captionedContent"]) {
- CMStringW wszUrl(content["url"].as_mstring());
- if (wszUrl.IsEmpty())
- return;
-
- if (!CheckFile(hContact, wszUrl, pFileInfo))
- return;
-
- CMStringW wszDescr(content["caption"].as_mstring());
- if (!wszDescr.IsEmpty())
- pFileInfo->wszDescr = wszDescr;
- }
- else {
- auto wszText = part["text"].as_mstring();
- CheckFile(hContact, wszText, pFileInfo);
- }
-}
-
-bool CIcqProto::RefreshRobustToken(AsyncHttpRequest *pOrigReq)
-{
- if (!m_szRToken.IsEmpty())
- return true;
-
- auto *pReq = new AsyncHttpRequest(CONN_RAPI, REQUEST_POST, ICQ_ROBUST_SERVER "/genToken", &CIcqProto::OnGenToken);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
-
- int ts = TS();
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", APP_ID) << CHAR_PARAM("nonce", CMStringA(FORMAT, "%d-%d", ts, rand() % 10)) << INT_PARAM("ts", ts);
- CalcHash(pReq);
-
- CMStringA szAgent(FORMAT, "%S Mail.ru Windows ICQ (version 10.0.1999)", (wchar_t*)m_szOwnId);
- pReq->AddHeader("User-Agent", szAgent);
- if (!ExecuteRequest(pReq)) {
-LBL_Error:
- (this->*(pOrigReq->m_pFunc))(nullptr, pOrigReq);
- return false;
- }
- if (m_szRToken.IsEmpty())
- goto LBL_Error;
-
- // now add this token
- bool bRet = false;
- pReq = new AsyncHttpRequest(CONN_RAPI, REQUEST_POST, ICQ_ROBUST_SERVER "/addClient", &CIcqProto::OnAddClient);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("f", "json") << CHAR_PARAM("k", APP_ID) << INT_PARAM("ts", ts)
- << CHAR_PARAM("client", "icq") << CHAR_PARAM("reqId", pReq->m_reqId) << CHAR_PARAM("authToken", m_szRToken);
- pReq->pUserInfo = &bRet;
- if (!ExecuteRequest(pReq))
- goto LBL_Error;
-
- return bRet;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGetUserCaps(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- JsonReply root(pReply);
- if (root.error() != 200)
- return;
-
- auto &data = root.data();
- for (auto &it : data["users"]) {
- ParseBuddyInfo(it, pReq->hContact, true);
-
- if (auto *pUser = (IcqUser *)pReq->pUserInfo)
- pUser->m_bGotCaps = true;
- }
-}
-
-void CIcqProto::RetrieveUserCaps(IcqUser *pUser)
-{
- auto *pReq = new AsyncHttpRequest(CONN_OLD, REQUEST_GET, "/presence/get", &CIcqProto::OnGetUserCaps);
- pReq->hContact = pUser->m_hContact;
- pReq->pUserInfo = pUser;
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("f", "json") << CHAR_PARAM("k", APP_ID) << CHAR_PARAM("r", pReq->m_reqId)
- << WCHAR_PARAM("t", GetUserId(pUser->m_hContact)) << INT_PARAM("mdir", 0) << INT_PARAM("capabilities", 1);
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGePresence(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- JsonReply root(pReply);
- if (root.error() != 200)
- return;
-
- auto &data = root.data();
- for (auto &it : data["users"]) {
- ParseBuddyInfo(it, pReq->hContact, true);
- ProcessOnline(it, pReq->hContact);
- }
-}
-
-void CIcqProto::RetrievePresence(MCONTACT hContact)
-{
- CMStringW wszId(GetUserId(hContact));
-
- auto *pReq = new AsyncHttpRequest(CONN_OLD, REQUEST_GET, "/presence/get", &CIcqProto::OnGePresence);
- pReq->hContact = hContact;
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("f", "json") << CHAR_PARAM("k", APP_ID) << CHAR_PARAM("r", pReq->m_reqId)
- << WCHAR_PARAM("t", wszId) << INT_PARAM("mdir", 1);
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGetUserInfo(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- RobustReply root(pReply);
- if (root.error() != 20000) {
- ProtoBroadcastAck(pReq->hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, nullptr);
- return;
- }
-
- ParseBuddyInfo(root.results(), pReq->hContact, true);
-
- ProtoBroadcastAck(pReq->hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, nullptr);
-}
-
-void CIcqProto::RetrieveUserInfo(MCONTACT hContact)
-{
- CMStringW wszId(GetUserId(hContact));
-
- auto *pReq = new AsyncRapiRequest(this, "getUserInfo", &CIcqProto::OnGetUserInfo);
- pReq->params << WCHAR_PARAM("sn", wszId);
- pReq->hContact = hContact;
- Push(pReq);
-
- if (hContact)
- if (auto *pUser = FindUser(wszId))
- if (!pUser->m_bGotCaps)
- RetrieveUserCaps(pUser);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGetPatches(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- RobustReply root(pReply);
- if (root.error() != 20000)
- return;
-
- auto &results = root.results();
-
- CMStringW wszNewPatch(results["patchVersion"].as_mstring());
- if (!wszNewPatch.IsEmpty())
- setId(pReq->hContact, DB_KEY_PATCHVER, _wtoi64(wszNewPatch));
-
- std::map<__int64, bool> events;
- for (auto &it : results["patch"]) {
- std::string type = it["type"].as_string();
- __int64 msgId = _wtoi64(it["msgId"].as_mstring());
- if (type == "update" || type == "modify")
- events[msgId] = true;
- else
- events[msgId] = false;
- }
-
- for (auto &it : events) {
- if (it.second) {
- bool bFound = false;
-
- for (auto &msg: results["messages"])
- if (_wtoi64(msg["msgId"].as_mstring()) == it.first) {
- bFound = true;
- __int64 lastMsgId;
- ParseMessage(pReq->hContact, lastMsgId, msg, PM::LocalTime);
- }
-
- if (!bFound)
- RetrieveHistoryChunk(pReq->hContact, it.first, it.first - 1, 1);
- }
- else {
- char msgId[100];
- _i64toa(it.first, msgId, 10);
- if (MEVENT hEvent = db_event_getById(m_szModuleName, msgId))
- db_event_delete(hEvent, CDF_FROM_SERVER);
- }
- }
-}
-
-void CIcqProto::ProcessPatchVersion(MCONTACT hContact, __int64 currPatch)
-{
- __int64 oldPatch(getId(hContact, DB_KEY_PATCHVER));
- if (!oldPatch)
- oldPatch = 1;
-
- if (currPatch == oldPatch)
- return;
-
- auto *pReq = new AsyncRapiRequest(this, "getHistory", &CIcqProto::OnGetPatches);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- pReq->hContact = hContact;
- pReq->params << WCHAR_PARAM("sn", GetUserId(hContact)) << INT_PARAM("fromMsgId", 0) << INT_PARAM("count", 0) << SINT64_PARAM("patchVersion", oldPatch);
- Push(pReq);
-}
-
-void CIcqProto::RetrievePatches(MCONTACT hContact)
-{
- __int64 oldPatch(getId(hContact, DB_KEY_PATCHVER));
- if (!oldPatch)
- oldPatch = 1;
-
- auto *pReq = new AsyncRapiRequest(this, "getHistory", &CIcqProto::OnGetPatches);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- pReq->hContact = hContact;
- pReq->params << WCHAR_PARAM("sn", GetUserId(hContact)) << INT_PARAM("fromMsgId", -1) << INT_PARAM("count", -1) << SINT64_PARAM("patchVersion", oldPatch);
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGetUserHistory(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- RobustReply root(pReply);
- if (root.error() != 20000)
- return;
-
- __int64 lastMsgId = getId(pReq->hContact, DB_KEY_LASTMSGID);
-
- wchar_t wszReceiveFolder[MAX_PATH];
- File::GetReceivedFolder(pReq->hContact, wszReceiveFolder, _countof(wszReceiveFolder), true);
- CreateDirectoryTreeW(wszReceiveFolder);
-
- int count = 0, flags = PM::FetchFiles + (pReq->pUserInfo ? PM::CreateRead : 0);
- auto &results = root.results();
- for (auto &it : results["messages"]) {
- ParseMessage(pReq->hContact, lastMsgId, it, flags);
- count++;
- }
-
- setId(pReq->hContact, DB_KEY_LASTMSGID, lastMsgId);
-
- if (count >= 999)
- RetrieveUserHistory(pReq->hContact, lastMsgId, flags);
-}
-
-void CIcqProto::RetrieveUserHistory(MCONTACT hContact, __int64 startMsgId, bool bCreateRead)
-{
- if (startMsgId == 0)
- startMsgId = -1;
-
- __int64 patchVer = getId(hContact, DB_KEY_PATCHVER);
- if (patchVer == 0)
- patchVer = 1;
-
- auto *pReq = new AsyncRapiRequest(this, "getHistory", &CIcqProto::OnGetUserHistory);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- pReq->hContact = hContact;
- pReq->pUserInfo = (bCreateRead) ? pReq : 0;
- pReq->params << WCHAR_PARAM("sn", GetUserId(hContact)) << INT64_PARAM("fromMsgId", startMsgId) << INT_PARAM("count", 1000) << SINT64_PARAM("patchVersion", patchVer);
- Push(pReq);
-}
-
-void CIcqProto::RetrieveHistoryChunk(MCONTACT hContact, __int64 patchVer, __int64 startMsgId, unsigned iCount)
-{
- auto *pReq = new AsyncRapiRequest(this, "getHistory", &CIcqProto::OnGetUserHistory);
- #ifndef _DEBUG
- pReq->flags |= NLHRF_NODUMPSEND;
- #endif
- pReq->hContact = hContact;
- pReq->params << WCHAR_PARAM("sn", GetUserId(hContact)) << INT64_PARAM("fromMsgId", startMsgId) << INT_PARAM("count", iCount) << SINT64_PARAM("patchVersion", patchVer);
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::SetOwnId(const CMStringW &wszId)
-{
- if (wszId.IsEmpty())
- return;
-
- m_szOwnId = wszId;
-
- auto *pUser = FindUser(wszId);
- if (!pUser) {
- CreateContact(wszId, false);
- pUser = FindUser(wszId);
- }
-
- setWString(pUser->m_hContact, "Nick", TranslateT("Favorites"));
- ptrW wszMyHandle(db_get_wsa(pUser->m_hContact, "CList", "MyHandle"));
- if (!wszMyHandle)
- db_set_ws(pUser->m_hContact, "CList", "MyHandle", TranslateT("Favorites"));
-
- if (m_hFavContact == INVALID_CONTACT_ID) {
- m_hFavContact = pUser->m_hContact;
- pUser->m_hContact = 0;
- }
-}
-
-void CIcqProto::SetServerStatus(int iStatus)
-{
- const char *szStatus = "online";
- m_bInvisible = false;
-
- switch (iStatus) {
- case ID_STATUS_OFFLINE: szStatus = "offline"; break;
- case ID_STATUS_NA: szStatus = "occupied"; break;
- case ID_STATUS_AWAY:
- case ID_STATUS_DND: szStatus = "away"; break;
- case ID_STATUS_INVISIBLE:
- m_bInvisible = true;
- }
-
- Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "/presence/setState")
- << AIMSID(this) << CHAR_PARAM("view", szStatus) << INT_PARAM("invisible", m_bInvisible));
-
- if (iStatus == ID_STATUS_OFFLINE && !getByte(DB_KEY_PHONEREG)) {
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, "/aim/endSession", &CIcqProto::OnSessionEnd);
- pReq << AIMSID(this) << INT_PARAM("invalidateToken", 1);
- ExecuteRequest(pReq);
- }
-
- int iOldStatus = m_iStatus; m_iStatus = iStatus;
- ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus);
-}
-
-void CIcqProto::ShutdownSession()
-{
- if (m_bTerminated)
- return;
-
- debugLogA("CIcqProto::ShutdownSession");
-
- // shutdown all resources
- DropQueue();
-
- if (m_hWorkerThread)
- SetEvent(m_evRequestsQueue);
-
- OnLoggedOut();
-
- for (auto &it : m_ConnPool) {
- if (it.s) {
- Netlib_Shutdown(it.s);
- it.s = nullptr;
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-#define EVENTS "myInfo,presence,buddylist,typing,dataIM,userAddedToBuddyList,mchat,hist,hiddenChat,diff,permitDeny,imState,notification,apps"
-#define FIELDS "aimId,buddyIcon,bigBuddyIcon,iconId,bigIconId,largeIconId,displayId,friendly,offlineMsg,state,statusMsg,userType,phoneNumber,cellNumber,smsNumber,workNumber,otherNumber,capabilities,ssl,abPhoneNumber,moodIcon,lastName,abPhones,abContactName,lastseen,mute,livechat,official"
-
-void CIcqProto::StartSession()
-{
- CMStringA szDeviceId(getMStringA("DeviceId"));
- if (szDeviceId.IsEmpty()) {
- szDeviceId = Utils_GenerateUUID();
- setString("DeviceId", szDeviceId);
- }
-
- int ts = TS();
- CMStringA nonce(FORMAT, "%d-2", ts);
- CMStringA caps(WIM_CAP_UNIQ_REQ_ID "," WIM_CAP_EMOJI "," WIM_CAP_MAIL_NOTIFICATIONS "," WIM_CAP_INTRO_DLG_STATE);
- if (g_bSecureIM) {
- caps.AppendChar(',');
- caps.Append(NG_CAP_SECUREIM);
- }
-
- MFileVersion v;
- Miranda_GetFileVersion(&v);
- caps.AppendFormat(",%02x%02x%02x%02x%02x%02x%02x%02x%04x%04x%04x%04x", 'M', 'i', 'N', 'G',
- __MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM, v[0], v[1], v[2], v[3]);
-
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_POST, "/aim/startSession", &CIcqProto::OnStartSession);
- pReq << CHAR_PARAM("a", m_szAToken) << INT_PARAM("activeTimeout", 180) << CHAR_PARAM("assertCaps", caps)
- << INT_PARAM("buildNumber", __BUILD_NUM) << CHAR_PARAM("deviceId", szDeviceId) << CHAR_PARAM("events", EVENTS)
- << CHAR_PARAM("f", "json") << CHAR_PARAM("imf", "plain") << CHAR_PARAM("inactiveView", "offline")
- << CHAR_PARAM("includePresenceFields", FIELDS) << CHAR_PARAM("invisible", "false")
- << CHAR_PARAM("k", APP_ID) << INT_PARAM("mobile", 0) << CHAR_PARAM("nonce", nonce) << CHAR_PARAM("r", pReq->m_reqId)
- << INT_PARAM("rawMsg", 0) << INT_PARAM("sessionTimeout", 7776000) << INT_PARAM("ts", ts) << CHAR_PARAM("view", "online");
-
- CalcHash(pReq);
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnAddBuddy(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- JsonReply root(pReply);
- if (root.error() != 200)
- return;
-
- CMStringW wszId = getMStringW(pReq->hContact, DB_KEY_ID);
- for (auto &it : root.data()["results"]) {
- if (it["buddy"].as_mstring() != wszId)
- continue;
-
- switch (int iResultCode = it["resultCode"].as_int()) {
- case 0: // success
- case 3: // already in contact list
- break;
-
- default:
- debugLogA("Contact %d failed to add: error %d", pReq->hContact, iResultCode);
-
- POPUPDATAW Popup = {};
- Popup.lchIcon = IcoLib_GetIconByHandle(Skin_GetIconHandle(SKINICON_ERROR));
- wcsncpy_s(Popup.lpwzText, TranslateT("Buddy addition failed"), _TRUNCATE);
- wcsncpy_s(Popup.lpwzContactName, Clist_GetContactDisplayName(pReq->hContact), _TRUNCATE);
- Popup.iSeconds = 20;
- PUAddPopupW(&Popup);
-
- // Contact::RemoveFromList(pReq->hContact);
- }
-
- RetrieveUserInfo(pReq->hContact);
- Contact::PutOnList(pReq->hContact);
- }
-}
-
-void CIcqProto::OnAddClient(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- bool *pRet = (bool*)pReq->pUserInfo;
-
- RobustReply reply(pReply);
- if (reply.error() != 20000) {
- *pRet = false;
- return;
- }
-
- const JSONNode &results = reply.results();
- m_iRClientId = results["clientId"].as_int();
- setDword(DB_KEY_RCLIENTID, m_iRClientId);
- *pRet = true;
-}
-
-void CIcqProto::OnCheckPassword(MHttpResponse *pReply, AsyncHttpRequest*)
-{
- JsonReply root(pReply);
- switch (root.error()) {
- case 200:
- break;
-
- case 330:
- case 440:
- ConnectionFailed(LOGINERR_WRONGPASSWORD, root.error());
- return;
-
- default:
- ConnectionFailed(LOGINERR_WRONGPROTOCOL, root.error());
- return;
- }
-
- JSONNode &data = root.data();
- m_szAToken = data["token"]["a"].as_mstring();
- mir_urlDecode(m_szAToken.GetBuffer());
- setString(DB_KEY_ATOKEN, m_szAToken);
-
- CMStringA szSessionSecret = data["sessionSecret"].as_mstring();
- CMStringA szPassTemp = m_szPassword;
-
- unsigned int len;
- uint8_t hashOut[MIR_SHA256_HASH_SIZE];
- HMAC(EVP_sha256(), szPassTemp, szPassTemp.GetLength(), (uint8_t*)szSessionSecret.c_str(), szSessionSecret.GetLength(), hashOut, &len);
- m_szSessionKey = ptrA(mir_base64_encode(hashOut, sizeof(hashOut)));
- setString(DB_KEY_SESSIONKEY, m_szSessionKey);
-
- SetOwnId(data["loginId"].as_mstring());
-
- int srvTS = data["hostTime"].as_int();
- m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
-
- StartSession();
-}
-
-void CIcqProto::OnFileContinue(MHttpResponse *pReply, AsyncHttpRequest *pOld)
-{
- IcqFileTransfer *pTransfer = (IcqFileTransfer*)pOld->pUserInfo;
- if (pTransfer->m_bCanceled) {
-LBL_Error:
- ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, pTransfer);
- delete pTransfer;
- return;
- }
-
- switch (pReply->resultCode) {
- case 200: // final ok
- case 206: // partial ok
- break;
-
- default:
- goto LBL_Error;
- }
-
- // file transfer succeeded?
- if (pTransfer->pfts.currentFileProgress == pTransfer->pfts.currentFileSize) {
- FileReply root(pReply);
- if (root.error() != 200)
- goto LBL_Error;
-
- const JSONNode &data = root.data();
- CMStringW wszUrl(data["static_url"].as_mstring());
-
- JSONNode bundle, contents; contents.set_name("captionedContent");
- contents << WCHAR_PARAM("caption", pTransfer->m_wszDescr) << WCHAR_PARAM("url", wszUrl);
- bundle << CHAR_PARAM("mediaType", "text") << WCHAR_PARAM("text", wszUrl) << contents;
- CMStringW wszParts(FORMAT, L"[%s]", ptrW(json_write(&bundle)).get());
-
- pTransfer->m_szHost = wszUrl;
- if (!pTransfer->m_wszDescr.IsEmpty())
- wszUrl += L" " + pTransfer->m_wszDescr;
-
- int id = InterlockedIncrement(&m_msgId);
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_POST, "/im/sendIM", &CIcqProto::OnSendMessage);
-
- auto *pOwn = new IcqOwnMessage(pTransfer->pfts.hContact, id, T2Utf(wszUrl));
- pOwn->setGuid(pReq->m_reqId);
- pOwn->pTransfer = pTransfer;
- pReq->pUserInfo = pOwn;
- {
- mir_cslock lck(m_csOwnIds);
- m_arOwnIds.insert(pOwn);
- }
-
- pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", APP_ID) << CHAR_PARAM("mentions", "") << WCHAR_PARAM("message", wszUrl)
- << CHAR_PARAM("offlineIM", "true") << WCHAR_PARAM("parts", wszParts) << WCHAR_PARAM("t", GetUserId(pTransfer->pfts.hContact)) << INT_PARAM("ts", TS());
- Push(pReq);
- return;
- }
-
- // else send the next portion
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, pTransfer->m_szHost, &CIcqProto::OnFileContinue);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", APP_ID) << INT_PARAM("ts", TS());
- CalcHash(pReq);
- pReq->m_szUrl.AppendChar('?');
- pReq->m_szUrl += pReq->m_szParam; pReq->m_szParam.Empty();
- pReq->pUserInfo = pTransfer;
- pTransfer->FillHeaders(pReq);
- Push(pReq);
-
- pTransfer->pfts.currentFileTime = time(0);
- ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, pTransfer, (LPARAM)&pTransfer->pfts);
-}
-
-void CIcqProto::OnFileInit(MHttpResponse *pReply, AsyncHttpRequest *pOld)
-{
- IcqFileTransfer *pTransfer = (IcqFileTransfer*)pOld->pUserInfo;
- if (pTransfer->m_bCanceled) {
-LBL_Error:
- ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, pTransfer);
- delete pTransfer;
- return;
- }
-
- FileReply root(pReply);
- if (root.error() != 200)
- goto LBL_Error;
-
- ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, pTransfer);
- pTransfer->pfts.currentFileTime = time(0);
-
- const JSONNode &data = root.data();
- CMStringW wszHost(data["host"].as_mstring());
- CMStringW wszUrl(data["url"].as_mstring());
- pTransfer->m_szHost = L"https://" + wszHost + wszUrl;
-
- auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, pTransfer->m_szHost, &CIcqProto::OnFileContinue);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", APP_ID) << INT_PARAM("ts", TS());
- CalcHash(pReq);
- pReq->m_szUrl.AppendChar('?');
- pReq->m_szUrl += pReq->m_szParam; pReq->m_szParam.Empty();
- pReq->pUserInfo = pTransfer;
- pTransfer->FillHeaders(pReq);
- Push(pReq);
-
- ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, pTransfer, (LPARAM)&pTransfer->pfts);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Support for stickers
-
-void CIcqProto::OnGetSticker(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- if (pReply->resultCode != 200) {
- debugLogA("Error getting sticker: %d", pReply->resultCode);
- return;
- }
-
- CMStringW wszPath(FORMAT, L"%s\\%S\\Stickers", VARSW(L"%miranda_avatarcache%").get(), m_szModuleName);
- CreateDirectoryTreeW(wszPath);
-
- CMStringW wszFileName(FORMAT, L"%s\\STK{%s}.png", wszPath.c_str(), (wchar_t*)pReq->pUserInfo);
- FILE *out = _wfopen(wszFileName, L"wb");
- fwrite(pReply->body, 1, pReply->body.GetLength(), out);
- fclose(out);
-
- SmileyAdd_LoadContactSmileys(SMADD_FILE, m_szModuleName, wszFileName);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnGenToken(MHttpResponse *pReply, AsyncHttpRequest*)
-{
- RobustReply root(pReply);
- if (root.error() != 20000)
- return;
-
- auto &results = root.results();
- m_szRToken = results["authToken"].as_mstring();
-}
-
-void CIcqProto::OnStartSession(MHttpResponse *pReply, AsyncHttpRequest *)
-{
- JsonReply root(pReply);
- switch (root.error()) {
- case 200:
- break;
-
- case 451:
- // session forcibly closed from site
- delSetting(DB_KEY_ATOKEN);
- delSetting(DB_KEY_SESSIONKEY);
- CheckPassword();
- return;
-
- case 401:
- delSetting(DB_KEY_ATOKEN);
- delSetting(DB_KEY_SESSIONKEY);
- if (root.detail() == 1002) // session expired
- CheckPassword();
- else
- ConnectionFailed(LOGINERR_WRONGPASSWORD, root.error());
- return;
-
- case 400:
- if (root.detail() == 1015 && m_iTimeShift == 0) { // wrong timestamp
- JSONNode &data = root.data();
- int srvTS = data["ts"].as_int();
- m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
- StartSession();
- return;
- }
- __fallthrough;
-
- default:
- ConnectionFailed(LOGINERR_WRONGPROTOCOL, root.error());
- return;
- }
-
- JSONNode &data = root.data();
- m_fetchBaseURL = data["fetchBaseURL"].as_mstring();
- m_aimsid = data["aimsid"].as_mstring();
-
- auto &myInfo = data["myInfo"];
- ProcessMyInfo(myInfo);
- SetOwnId(myInfo["aimId"].as_mstring());
-
- int srvTS = data["ts"].as_int();
- m_iTimeShift = (srvTS) ? time(0) - srvTS : 0;
-
- for (auto &it : data["events"])
- ProcessEvent(it);
-
- OnLoggedIn();
-
- ForkThread(&CIcqProto::PollThread);
-}
-
-void CIcqProto::OnReceiveAvatar(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- PROTO_AVATAR_INFORMATION ai = {};
- ai.hContact = pReq->hContact;
-
- if (pReply->resultCode != 200 || pReply->body.IsEmpty()) {
-LBL_Error:
- ProtoBroadcastAck(pReq->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai);
- return;
- }
-
- const char *szContentType = pReply->FindHeader("Content-Type");
- if (szContentType == nullptr)
- szContentType = "image/jpeg";
-
- ai.format = ProtoGetAvatarFormatByMimeType(szContentType);
- setByte(pReq->hContact, "AvatarType", ai.format);
- GetAvatarFileName(pReq->hContact, ai.filename, _countof(ai.filename));
-
- FILE *out = _wfopen(ai.filename, L"wb");
- if (out == nullptr)
- goto LBL_Error;
-
- fwrite(pReply->body, pReply->body.GetLength(), 1, out);
- fclose(out);
-
- if (pReq->hContact != 0) {
- ProtoBroadcastAck(pReq->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai);
- debugLogW(L"Broadcast new avatar: %s", ai.filename);
- }
- else ReportSelfAvatarChanged();
-}
-
-void CIcqProto::OnSearchResults(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- RobustReply root(pReply);
- if (root.error() != 20000) {
- ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)pReq, 0);
- return;
- }
-
- const JSONNode &results = root.results();
-
- PROTOSEARCHRESULT psr = {};
- psr.cbSize = sizeof(psr);
- psr.flags = PSR_UNICODE;
- for (auto &it : results["persons"]) {
- CMStringW wszId = it["sn"].as_mstring();
- if (wszId == m_szOwnId)
- continue;
-
- CMStringW wszNick = it["friendly"].as_mstring();
- CMStringW wszFirst = it["firstName"].as_mstring();
- CMStringW wszLast = it["lastName"].as_mstring();
-
- psr.id.w = wszId.GetBuffer();
- psr.nick.w = wszNick.GetBuffer();
- psr.firstName.w = wszFirst.GetBuffer();
- psr.lastName.w = wszLast.GetBuffer();
- ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)pReq, LPARAM(&psr));
- }
-
- ProtoBroadcastAck(0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::PatchProfileInfo(const char *pszVariable, const wchar_t *pwszValue)
-{
- if (!mir_wstrlen(pwszValue))
- return;
-
- auto *pReq = new AsyncRapiRequest(this, "/profile/update", nullptr, 1);
- pReq->params << WCHAR_PARAM(pszVariable, pwszValue);
- Push(pReq);
-
- char *buf = NEWSTR_ALLOCA(pszVariable);
- buf[0] = _toupper(buf[0]);
- setWString(buf, pwszValue);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Send message
-
-void CIcqProto::OnSendMessage(MHttpResponse *pReply, AsyncHttpRequest *pReq)
-{
- IcqOwnMessage *ownMsg = (IcqOwnMessage *)pReq->pUserInfo;
-
- JsonReply root(pReply);
- if (root.error() != 200) {
- if (ownMsg) {
- ProtoBroadcastAck(ownMsg->m_hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)ownMsg->m_msgid);
-
- mir_cslock lck(m_csOwnIds);
- m_arOwnIds.remove(ownMsg);
- }
- return;
- }
-
- const JSONNode &data = root.data();
- if (auto &jsonMsg = data.at("histMsgId")) {
- CMStringA reqId(root.requestId());
- CMStringA msgId(jsonMsg.as_mstring());
- CheckOwnMessage(reqId, msgId, false);
- }
-
- if (ownMsg) {
- if (g_bMessageState)
- CallService(MS_MESSAGESTATE_UPDATE, ownMsg->m_hContact, MRD_TYPE_DELIVERED);
- CheckLastId(ownMsg->m_hContact, data);
- }
-}
-
-void CIcqProto::SendMessageParts(MCONTACT hContact, const JSONNode &parts, IcqOwnMessage *pOwn)
-{
- CMStringA szUserid(GetUserId(hContact));
- if (szUserid.IsEmpty())
- return;
-
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_POST, "/im/sendIM", &CIcqProto::OnSendMessage);
- pReq->pUserInfo = pOwn;
- if (pOwn)
- pOwn->setGuid(pReq->m_reqId);
-
- pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", APP_ID) << CHAR_PARAM("mentions", "")
- << CHAR_PARAM("offlineIM", "true") << CHAR_PARAM("parts", parts.write().c_str()) << CHAR_PARAM("t", szUserid) << INT_PARAM("ts", TS());
- Push(pReq);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::OnSessionEnd(MHttpResponse *pReply, AsyncHttpRequest *)
-{
- JsonReply root(pReply);
- if (root.error() == 200) {
- m_szAToken.Empty();
- delSetting(DB_KEY_ATOKEN);
-
- m_szSessionKey.Empty();
- delSetting(DB_KEY_SESSIONKEY);
-
- ShutdownSession();
- }
-}
diff --git a/protocols/ICQ-WIM/src/stdafx.cxx b/protocols/ICQ-WIM/src/stdafx.cxx deleted file mode 100644 index 87b7477097..0000000000 --- a/protocols/ICQ-WIM/src/stdafx.cxx +++ /dev/null @@ -1,18 +0,0 @@ -/*
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
-
-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 version 2
-of the License.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdafx.h"
diff --git a/protocols/ICQ-WIM/src/stdafx.h b/protocols/ICQ-WIM/src/stdafx.h deleted file mode 100644 index d2a7be4afc..0000000000 --- a/protocols/ICQ-WIM/src/stdafx.h +++ /dev/null @@ -1,115 +0,0 @@ -// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2010 Joe Kucera
-// Copyright © 2012-2024 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Includes all header files that should be precompiled to speed up compilation.
-// -----------------------------------------------------------------------------
-
-#pragma once
-
-// Windows includes
-#include <windows.h>
-
-#include <map>
-#include <memory>
-
-// Standard includes
-#include <stdio.h>
-#include <time.h>
-#include <io.h>
-#include <malloc.h>
-#include <direct.h>
-#include <fcntl.h>
-#include <process.h>
-
-// Miranda IM SDK includes
-#include <newpluginapi.h> // This must be included first
-#include <m_avatars.h>
-#include <m_chat_int.h>
-#include <m_clistint.h>
-#include <m_contacts.h>
-#include <m_database.h>
-#include <m_file.h>
-#include <m_gui.h>
-#include <m_idle.h>
-#include <m_icolib.h>
-#include <m_ignore.h>
-#include <m_json.h>
-#include <m_langpack.h>
-#include <m_message.h>
-#include <m_messagestate.h>
-#include <m_netlib.h>
-#include <m_NewStory.h>
-#include <m_protocols.h>
-#include <m_protosvc.h>
-#include <m_options.h>
-#include <m_popup.h>
-#include <m_skin.h>
-#include <m_smileyadd.h>
-#include <m_system.h>
-#include <m_timezones.h>
-#include <m_userinfo.h>
-#include <m_utils.h>
-
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/rand.h>
-#include <openssl/sha.h>
-
-// Project resources
-#include "resource.h"
-
-// ICQ plugin includes
-#include "version.h"
-
-#define MODULENAME "MRA"
-
-#define DB_KEY_ID "aimId"
-#define DB_KEY_ABOUT "About"
-#define DB_KEY_PHONE "Phone"
-#define DB_KEY_ATOKEN "AToken"
-#define DB_KEY_ICQNICK "IcqNick"
-#define DB_KEY_PHONEREG "PhoneReg"
-#define DB_KEY_LASTSEEN "LastSeen"
-#define DB_KEY_ONLINETS "OnlineTS"
-#define DB_KEY_PATCHVER "PatchVersion"
-#define DB_KEY_RCLIENTID "RClientID"
-#define DB_KEY_LASTMSGID "LastMsgId"
-#define DB_KEY_REMOTEREAD "RemoteReadId"
-#define DB_KEY_SESSIONKEY "SessionKey"
-
-#include "http.h"
-#include "proto.h"
-
-bool IsChat(const CMStringW &aimid);
-bool IsValidType(const JSONNode &aimid);
-
-void RefreshGroups(void);
-wchar_t* time2text(time_t time);
-wchar_t* time2text(DBVARIANT *dbv);
-
-int fileText2url(const CMStringW &wszText, CMStringW *res = nullptr);
-
-extern bool g_bSecureIM, g_bMessageState;
diff --git a/protocols/ICQ-WIM/src/userinfo.cpp b/protocols/ICQ-WIM/src/userinfo.cpp deleted file mode 100644 index 9d7de17592..0000000000 --- a/protocols/ICQ-WIM/src/userinfo.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-struct IcqUserInfoDlg : public CUserInfoPageDlg
-{
- CIcqProto *ppro;
- HANDLE hEvent = 0;
- CCtrlEdit edtFirstName, edtLastName;
-
- IcqUserInfoDlg(CIcqProto *_ppro) :
- CUserInfoPageDlg(g_plugin, IDD_INFO_ICQ),
- ppro(_ppro),
- edtLastName(this, IDC_LAST_NAME),
- edtFirstName(this, IDC_FIRST_NAME)
- {
- }
-
- bool OnInitDialog() override
- {
- hEvent = HookEventMessage(ME_DB_CONTACT_SETTINGCHANGED, m_hwnd, WM_USER);
- return true;
- }
-
- bool OnApply() override
- {
- if (edtFirstName.IsChanged())
- ppro->PatchProfileInfo("firstName", ptrW(edtFirstName.GetText()));
- if (edtLastName.IsChanged())
- ppro->PatchProfileInfo("lastName", ptrW(edtLastName.GetText()));
- return true;
- }
-
- void OnDestroy() override
- {
- UnhookEvent(hEvent);
- }
-
- UI_MESSAGE_MAP(IcqUserInfoDlg, CUserInfoPageDlg);
- UI_MESSAGE(WM_USER, OnSettingChanged);
- UI_MESSAGE_MAP_END();
-
- LRESULT OnSettingChanged(UINT, WPARAM hContact, LPARAM)
- {
- if (hContact == m_hContact)
- OnRefresh();
- return 0;
- }
-
- bool OnRefresh() override
- {
- SetDlgItemTextW(m_hwnd, IDC_UIN, ppro->GetUserId(m_hContact));
- SetDlgItemTextW(m_hwnd, IDC_NICK, ppro->getMStringW(m_hContact, DB_KEY_ICQNICK));
- SetDlgItemTextW(m_hwnd, IDC_PHONE, ppro->getMStringW(m_hContact, DB_KEY_PHONE));
-
- edtLastName.SetText(ppro->getMStringW(m_hContact, "LastName"));
- edtFirstName.SetText(ppro->getMStringW(m_hContact, "FirstName"));
-
- DBVARIANT dbv = {};
- if (!db_get(m_hContact, ppro->m_szModuleName, DB_KEY_LASTSEEN, &dbv)) {
- SetDlgItemTextW(m_hwnd, IDC_LASTSEEN, time2text(&dbv));
- db_free(&dbv);
- }
-
- if (!db_get(m_hContact, ppro->m_szModuleName, DB_KEY_ONLINETS, &dbv)) {
- SetDlgItemTextW(m_hwnd, IDC_ONLINESINCE, time2text(&dbv));
- db_free(&dbv);
- }
-
- return false;
- }
-};
-
-struct IcqAboutDlg : public CUserInfoPageDlg
-{
- CIcqProto *ppro;
- CCtrlEdit edtAbout;
-
- IcqAboutDlg(CIcqProto *_ppro) :
- CUserInfoPageDlg(g_plugin, IDD_ABOUT),
- ppro(_ppro),
- edtAbout(this, IDC_ABOUT)
- {}
-
- bool OnRefresh() override
- {
- edtAbout.SetText(ppro->getMStringW(m_hContact, "About"));
- return false;
- }
-
- bool OnApply() override
- {
- if (edtAbout.IsChanged())
- ppro->PatchProfileInfo("about", ptrW(edtAbout.GetText()));
- return true;
- }
-
- int Resizer(UTILRESIZECONTROL *urc) override
- {
- if (urc->wId == IDC_ABOUT)
- return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
-
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
- }
-};
-
-int CIcqProto::OnUserInfoInit(WPARAM wParam, LPARAM hContact)
-{
- if (hContact && mir_strcmp(Proto_GetBaseAccountName(hContact), m_szModuleName))
- return 0;
-
- if (isChatRoom(hContact))
- return 0;
-
- USERINFOPAGE uip = {};
- uip.flags = ODPF_UNICODE | ODPF_USERINFOTAB | ODPF_DONTTRANSLATE;
- uip.szGroup.w = m_tszUserName;
- uip.szProto = m_szModuleName;
-
- uip.szTitle.w = L"MRA";
- uip.position = -1900000000;
- uip.pDialog = new IcqUserInfoDlg(this);
- g_plugin.addUserInfo(wParam, &uip);
-
- uip.szTitle.w = TranslateT("About");
- uip.position = -1900000001;
- uip.pDialog = new IcqAboutDlg(this);
- g_plugin.addUserInfo(wParam, &uip);
- return 0;
-}
diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp deleted file mode 100644 index 722314bc55..0000000000 --- a/protocols/ICQ-WIM/src/utils.cpp +++ /dev/null @@ -1,341 +0,0 @@ -// -----------------------------------------------------------------------------
-// ICQ plugin for Miranda NG
-// -----------------------------------------------------------------------------
-// Copyright © 2018-24 Miranda NG team
-//
-// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// -----------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-IcqUser* CIcqProto::FindUser(const CMStringW &wszId)
-{
- IcqUser tmp(wszId, -1);
-
- mir_cslock l(m_csCache);
- return m_arCache.find(&tmp);
-}
-
-wchar_t* CIcqProto::GetUIN(MCONTACT hContact)
-{
- DBVARIANT dbv = {};
- if (!db_get(hContact, m_szModuleName, "UIN", &dbv)) {
- switch (dbv.type) {
- case DBVT_DWORD:
- wchar_t buf[40], *ret;
- _itow_s(dbv.dVal, buf, 10);
- return mir_wstrdup(buf);
-
- case DBVT_ASCIIZ:
- ret = mir_a2u(dbv.pszVal);
- db_free(&dbv);
- return ret;
-
- case DBVT_UTF8:
- ret = mir_utf8decodeW(dbv.pszVal);
- db_free(&dbv);
- return ret;
-
- case DBVT_WCHAR:
- return dbv.pwszVal;
- }
- db_free(&dbv);
- }
- return nullptr;
-}
-
-MCONTACT CIcqProto::CreateContact(const CMStringW &wszId, bool bTemporary)
-{
- auto *pUser = FindUser(wszId);
- if (pUser != nullptr)
- return GetRealContact(pUser);
-
- MCONTACT hContact = db_add_contact();
- setWString(hContact, DB_KEY_ID, wszId);
- Proto_AddToContact(hContact, m_szModuleName);
- RetrieveUserInfo(hContact);
-
- if (bTemporary)
- Contact::RemoveFromList(hContact);
-
- return hContact;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::CalcHash(AsyncHttpRequest *pReq)
-{
- CMStringA hashData(FORMAT, "%s&%s&%s",
- pReq->requestType == REQUEST_POST ? "POST" : "GET",
- mir_urlEncode(pReq->m_szUrl).c_str(), mir_urlEncode(pReq->m_szParam).c_str());
-
- unsigned int len;
- uint8_t hashOut[MIR_SHA256_HASH_SIZE];
- HMAC(EVP_sha256(), m_szSessionKey, m_szSessionKey.GetLength(), (uint8_t*)hashData.c_str(), hashData.GetLength(), hashOut, &len);
- pReq << CHAR_PARAM("sig_sha256", ptrA(mir_base64_encode(hashOut, sizeof(hashOut))));
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::Json2int(MCONTACT hContact, const JSONNode &node, const char *szJson, const char *szSetting, bool bIsPartial)
-{
- const JSONNode &var = node[szJson];
- if (var)
- setDword(hContact, szSetting, var.as_int());
- else if (!bIsPartial)
- delSetting(hContact, szSetting);
-}
-
-void CIcqProto::Json2string(MCONTACT hContact, const JSONNode &node, const char *szJson, const char *szSetting, bool bIsPartial)
-{
- const JSONNode &var = node[szJson];
- if (var) {
- CMStringW wszStr(var.as_mstring());
- if (wszStr == L"[deleted]") {
- setByte(hContact, "IcqDeleted", 1);
- Contact::PutOnList(hContact);
- }
- else setWString(hContact, szSetting, wszStr);
- }
- else if (!bIsPartial)
- delSetting(hContact, szSetting);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-MCONTACT CIcqProto::GetRealContact(IcqUser *pUser)
-{
- return (pUser->m_hContact == 0) ? m_hFavContact : pUser->m_hContact;
-}
-
-CMStringW CIcqProto::GetUserId(MCONTACT hContact)
-{
- return getMStringW(hContact, DB_KEY_ID);
-}
-
-bool IsChat(const CMStringW &aimid)
-{
- return aimid.Right(11) == "@chat.agent";
-}
-
-bool IsValidType(const JSONNode &n)
-{
- auto type = n["userType"].as_string();
- return type == "icq" || type == "aim" || type == "interop" || type == "";
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CIcqProto::ProcessOnline(const JSONNode &presence, MCONTACT hContact)
-{
- int onlineTime = presence["onlineTime"].as_int();
- if (onlineTime)
- setDword(hContact, DB_KEY_ONLINETS, time(0) - onlineTime);
- else
- delSetting(hContact, DB_KEY_ONLINETS);
-}
-
-int CIcqProto::StatusFromPresence(const JSONNode &presence, MCONTACT hContact)
-{
- auto *pUser = FindUser(GetUserId(hContact));
- if (pUser == nullptr)
- return -1;
-
- CMStringW wszStatus = presence["state"].as_mstring();
- int iStatus;
- if (wszStatus == L"online") {
- pUser->m_bWasOnline = true;
- iStatus = ID_STATUS_ONLINE;
- }
- else if (wszStatus == L"offline")
- iStatus = ID_STATUS_OFFLINE;
- else if (wszStatus == L"n/a")
- iStatus = ID_STATUS_NA;
- else if (wszStatus == L"away")
- iStatus = ID_STATUS_AWAY;
- else if (wszStatus == L"occupied")
- iStatus = ID_STATUS_OCCUPIED;
- else if (wszStatus == L"dnd")
- iStatus = ID_STATUS_DND;
- else
- return -1;
-
- int iLastSeen = presence["lastseen"].as_int();
- if (iLastSeen != 0) {
- if (iLastSeen == 1388520000) // 01/01/2014, 00:00 GMT
- setWString(hContact, DB_KEY_LASTSEEN, TranslateT("long time ago"));
- else
- setDword(hContact, DB_KEY_LASTSEEN, iLastSeen);
- }
- else {
- if (!pUser->m_bWasOnline)
- return -1;
-
- iStatus = ID_STATUS_ONLINE;
- }
-
- return iStatus;
-}
-
-void CIcqProto::ProcessStatus(IcqUser *pUser, int iStatus)
-{
- // major crutch dedicated to the official client behaviour to go offline
- // when its window gets closed. we change the status of a contact to the
- // first chosen one from options and initialize a timer
- if (iStatus == ID_STATUS_OFFLINE) {
- if (m_iTimeDiff1) {
- iStatus = m_iStatus1;
- pUser->m_timer1 = time(0);
- }
- }
- // if a client returns back online, we clear timers not to play with statuses anymore
- else pUser->m_timer1 = pUser->m_timer2 = 0;
-
- if (iStatus == ID_STATUS_ONLINE && !pUser->m_bGotCaps)
- RetrieveUserCaps(pUser);
-
- setWord(pUser->m_hContact, "Status", iStatus);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-__int64 CIcqProto::getId(MCONTACT hContact, const char *szSetting)
-{
- DBVARIANT dbv;
- dbv.type = DBVT_BLOB;
- if (db_get(hContact, m_szModuleName, szSetting, &dbv))
- return 0;
-
- __int64 result = (dbv.cpbVal == sizeof(__int64)) ? *(__int64*)dbv.pbVal : 0;
- db_free(&dbv);
- return result;
-}
-
-void CIcqProto::setId(MCONTACT hContact, const char *szSetting, __int64 iValue)
-{
- __int64 oldVal = getId(hContact, szSetting);
- if (oldVal != iValue)
- db_set_blob(hContact, m_szModuleName, szSetting, &iValue, sizeof(iValue));
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int fileText2url(const CMStringW &wszText, CMStringW *res)
-{
- int iStart = 0;
- if (!mir_wstrncmp(wszText, L"https://files.icq.net/get/", 26)) {
- if (res)
- *res = wszText.Mid(iStart = 26);
- }
- else if (!mir_wstrncmp(wszText, L"http://files.icq.net/get/", 25)) {
- if (res)
- *res = wszText.Mid(iStart = 25);
- }
- else return 0;
-
- if (res) {
- int idx = res->FindOneOf(L" \r\n\t");
- if (idx == -1)
- return -1;
-
- *res = res->Mid(0, idx);
- return iStart + idx;
- }
-
- return 1;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static wchar_t g_statBuf[100];
-
-wchar_t* time2text(DBVARIANT *dbv)
-{
- switch (dbv->type) {
- case DBVT_WCHAR:
- return dbv->pwszVal;
-
- case DBVT_DWORD:
- return time2text(time_t(dbv->dVal));
-
- case DBVT_UTF8:
- wcsncpy_s(g_statBuf, Utf2T(dbv->pszVal), _TRUNCATE);
- return g_statBuf;
- }
-
- return L"";
-}
-
-wchar_t* time2text(time_t ts)
-{
- if (ts == 0)
- return L"";
-
- TimeZone_PrintTimeStamp(NULL, ts, L"D t", g_statBuf, _countof(g_statBuf), 0);
- return g_statBuf;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch (message) {
- case WM_CONTEXTMENU:
- PUDeletePopup(hWnd);
- break;
-
- case WM_COMMAND:
- CIcqProto *ppro = (CIcqProto*)PUGetPluginData(hWnd);
- CallProtoService(ppro->m_szModuleName, PS_GOTO_INBOX);
- PUDeletePopup(hWnd);
- break;
- }
-
- return DefWindowProc(hWnd, message, wParam, lParam);
-}
-
-void CIcqProto::EmailNotification(const wchar_t *pwszText)
-{
- POPUPDATAW Popup = {};
- Popup.lchIcon = g_plugin.getIcon(IDI_INBOX);
- wcsncpy_s(Popup.lpwzText, pwszText, _TRUNCATE);
- wcsncpy_s(Popup.lpwzContactName, m_tszUserName, _TRUNCATE);
- Popup.iSeconds = 20;
- Popup.PluginData = this;
- Popup.PluginWindowProc = PopupDlgProc;
- PUAddPopupW(&Popup);
-
- if (m_bUseTrayIcon) {
- char szServiceFunction[MAX_PATH];
- if (m_bLaunchMailbox)
- mir_snprintf(szServiceFunction, "%s%s", m_szModuleName, PS_GOTO_INBOX);
- else
- mir_snprintf(szServiceFunction, "%s%s", m_szModuleName, PS_DUMMY);
-
- int i = 0;
- while (auto *pcle = Clist_GetEvent(-1, i++))
- if (!mir_strcmp(pcle->pszService, szServiceFunction))
- return;
-
- CLISTEVENT cle = {};
- cle.hDbEvent = ICQ_FAKE_EVENT_ID;
- cle.moduleName = m_szModuleName;
- cle.hIcon = g_plugin.getIcon(IDI_INBOX);
- cle.flags = CLEF_UNICODE | CLEF_PROTOCOLGLOBAL;
- cle.pszService = szServiceFunction;
- cle.szTooltip.w = pwszText;
- g_clistApi.pfnAddEvent(&cle);
- }
-}
diff --git a/protocols/ICQ-WIM/src/version.h b/protocols/ICQ-WIM/src/version.h deleted file mode 100644 index 57e813a899..0000000000 --- a/protocols/ICQ-WIM/src/version.h +++ /dev/null @@ -1,13 +0,0 @@ -#define __MAJOR_VERSION 0
-#define __MINOR_VERSION 96
-#define __RELEASE_NUM 5
-#define __BUILD_NUM 1
-
-#include <stdver.h>
-
-#define __PLUGIN_NAME "WIM protocol"
-#define __FILENAME "ICQ.dll"
-#define __DESCRIPTION "MRA protocol support for Miranda NG."
-#define __AUTHOR "George Hazan"
-#define __AUTHORWEB "https://miranda-ng.org/p/MRA"
-#define __COPYRIGHT "© 2018-24 George Hazan"
|