summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2015-03-17 20:33:47 +0000
committerAlexander Lantsev <aunsane@gmail.com>2015-03-17 20:33:47 +0000
commitdd3d0e59dcd34beb222fcf612a51d3fee82c0e43 (patch)
tree0ae5a6e0a83399036d1452256ee3f89dc6da8872
parent076fa9b3142f55fc736fbf58b20bfa45973acd68 (diff)
SkypeWeb: initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@12424 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/SkypeWeb/SkypeWeb_12.vcxproj241
-rw-r--r--protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters103
-rw-r--r--protocols/SkypeWeb/res/Icons/skype.icobin0 -> 5430 bytes
-rw-r--r--protocols/SkypeWeb/res/resource.rc180
-rw-r--r--protocols/SkypeWeb/res/version.rc38
-rw-r--r--protocols/SkypeWeb/src/common.h60
-rw-r--r--protocols/SkypeWeb/src/http_request.h83
-rw-r--r--protocols/SkypeWeb/src/main.cpp62
-rw-r--r--protocols/SkypeWeb/src/request_queue.cpp88
-rw-r--r--protocols/SkypeWeb/src/request_queue.h50
-rw-r--r--protocols/SkypeWeb/src/requests/login.h44
-rw-r--r--protocols/SkypeWeb/src/requests/logout.h13
-rw-r--r--protocols/SkypeWeb/src/resource.h23
-rw-r--r--protocols/SkypeWeb/src/skype_accounts.cpp51
-rw-r--r--protocols/SkypeWeb/src/skype_contacts.cpp103
-rw-r--r--protocols/SkypeWeb/src/skype_events.cpp93
-rw-r--r--protocols/SkypeWeb/src/skype_icons.cpp63
-rw-r--r--protocols/SkypeWeb/src/skype_icons.h12
-rw-r--r--protocols/SkypeWeb/src/skype_menus.cpp97
-rw-r--r--protocols/SkypeWeb/src/skype_menus.h11
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp29
-rw-r--r--protocols/SkypeWeb/src/skype_options.cpp96
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp174
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h180
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp40
-rw-r--r--protocols/SkypeWeb/src/stdafx.cpp18
-rw-r--r--protocols/SkypeWeb/src/version.h14
27 files changed, 1966 insertions, 0 deletions
diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj b/protocols/SkypeWeb/SkypeWeb_12.vcxproj
new file mode 100644
index 0000000000..824dd30c22
--- /dev/null
+++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.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">
+ <ProjectGuid>{66A9BDEB-150F-45DC-B20F-9892C0B43834}</ProjectGuid>
+ <ProjectName>SkypeWeb</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120_xp</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120_xp</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120_xp</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120_xp</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>include;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <StringPooling>false</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin12\lib</AdditionalLibraryDirectories>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>include;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <StringPooling>false</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin12\lib</AdditionalLibraryDirectories>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ </Link>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>include;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin12\lib</AdditionalLibraryDirectories>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Full</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>include;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(ProfileDir)..\..\bin12\lib</AdditionalLibraryDirectories>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="src\common.h" />
+ <ClInclude Include="src\http_request.h" />
+ <ClInclude Include="src\requests\login.h" />
+ <ClInclude Include="src\requests\logout.h" />
+ <ClInclude Include="src\resource.h" />
+ <ClInclude Include="src\skype_icons.h" />
+ <ClInclude Include="src\skype_menus.h" />
+ <ClInclude Include="src\skype_proto.h" />
+ <ClInclude Include="src\request_queue.h" />
+ <ClInclude Include="src\version.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\main.cpp" />
+ <ClCompile Include="src\request_queue.cpp" />
+ <ClCompile Include="src\stdafx.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\skype_accounts.cpp" />
+ <ClCompile Include="src\skype_events.cpp" />
+ <ClCompile Include="src\skype_icons.cpp" />
+ <ClCompile Include="src\skype_menus.cpp" />
+ <ClCompile Include="src\skype_messages.cpp" />
+ <ClCompile Include="src\skype_options.cpp" />
+ <ClCompile Include="src\skype_proto.cpp" />
+ <ClCompile Include="src\skype_contacts.cpp" />
+ <ClCompile Include="src\skype_utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\resource.rc" />
+ <ResourceCompile Include="res\version.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="res\icons\skype.ico" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters
new file mode 100644
index 0000000000..3e97d03543
--- /dev/null
+++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{86de5614-9de5-4ffc-bd34-21d9c671e172}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{ea03e4bb-b8dd-4b5b-b409-2513240d2511}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{b818611d-200d-4eb8-be7a-f15b396ae26d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files\Icons">
+ <UniqueIdentifier>{5ce796e5-1f0d-4bb7-bdab-9de0e5513528}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files\requests">
+ <UniqueIdentifier>{957f1f93-0eaa-46b2-8f18-5df27d47239e}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\skype_proto.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\skype_menus.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\skype_icons.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\http_request.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\request_queue.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\requests\login.h">
+ <Filter>Header Files\requests</Filter>
+ </ClInclude>
+ <ClInclude Include="src\requests\logout.h">
+ <Filter>Header Files\requests</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_accounts.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_contacts.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_events.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_icons.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_menus.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_messages.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_proto.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\skype_utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\request_queue.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="res\version.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="res\icons\skype.ico">
+ <Filter>Resource Files\Icons</Filter>
+ </Image>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/protocols/SkypeWeb/res/Icons/skype.ico b/protocols/SkypeWeb/res/Icons/skype.ico
new file mode 100644
index 0000000000..e69f22e023
--- /dev/null
+++ b/protocols/SkypeWeb/res/Icons/skype.ico
Binary files differ
diff --git a/protocols/SkypeWeb/res/resource.rc b/protocols/SkypeWeb/res/resource.rc
new file mode 100644
index 0000000000..6e79cc7696
--- /dev/null
+++ b/protocols/SkypeWeb/res/resource.rc
@@ -0,0 +1,180 @@
+// 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
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral (Default) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD)
+LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
+#pragma code_page(1251)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_SKYPE ICON "icons\\skype.ico"
+#endif // Neutral (Default) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian (Russia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON "Icons\\skype.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "..\\src\\resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian (Russia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ACCOUNT_MANAGER DIALOGEX 0, 0, 186, 119
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_PASSWORD,49,16,135,12,ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "Login:",IDC_STATIC,0,2,49,12
+ EDITTEXT IDC_LOGIN,49,0,135,12,ES_AUTOHSCROLL
+ LTEXT "Password:",IDC_STATIC,0,18,49,12
+ LTEXT "Default group:",IDC_STATIC,0,34,49,12
+ EDITTEXT IDC_GROUP,49,32,135,12,ES_AUTOHSCROLL
+END
+
+IDD_OPTIONS_MAIN DIALOGEX 0, 0, 310, 230
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Account",IDC_STATIC,7,7,296,63,NOT WS_VISIBLE
+ LTEXT "Name:",IDC_STATIC,12,19,69,11
+ EDITTEXT IDC_LOGIN,81,17,217,12,ES_AUTOHSCROLL
+ LTEXT "Password:",IDC_STATIC,12,34,69,8
+ EDITTEXT IDC_PASSWORD,81,33,217,12,ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "Default group:",IDC_STATIC,12,51,69,12
+ EDITTEXT IDC_GROUP,81,49,217,12,ES_AUTOHSCROLL
+END
+
+IDD_PASSWORD_EDITOR DIALOGEX 0, 0, 209, 75
+STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW | WS_EX_APPWINDOW
+CAPTION "Enter password"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_PASSWORD,7,24,197,12,ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "Save password",IDC_SAVEPERMANENTLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,40,197,12
+ DEFPUSHBUTTON "OK",IDOK,101,56,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,154,56,50,14
+ LTEXT "Enter the password to continue.",IDC_STATIC,7,5,197,18
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ACCOUNT_MANAGER, DIALOG
+ BEGIN
+ VERTGUIDE, 49
+ BOTTOMMARGIN, 112
+ END
+
+ IDD_OPTIONS_MAIN, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 303
+ VERTGUIDE, 12
+ VERTGUIDE, 81
+ VERTGUIDE, 298
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 228
+ END
+
+ IDD_PASSWORD, DIALOG
+ BEGIN
+ RIGHTMARGIN, 204
+ VERTGUIDE, 7
+ BOTTOMMARGIN, 70
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/protocols/SkypeWeb/res/version.rc b/protocols/SkypeWeb/res/version.rc
new file mode 100644
index 0000000000..5bfbab4754
--- /dev/null
+++ b/protocols/SkypeWeb/res/version.rc
@@ -0,0 +1,38 @@
+// Microsoft Visual C++ generated resource script.
+//
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+#include "afxres.h"
+#include "..\src\version.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "FileDescription", __DESCRIPTION
+ VALUE "InternalName", __PLUGIN_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ VALUE "OriginalFilename", __FILENAME
+ VALUE "ProductName", __PLUGIN_NAME
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h
new file mode 100644
index 0000000000..511fafb404
--- /dev/null
+++ b/protocols/SkypeWeb/src/common.h
@@ -0,0 +1,60 @@
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <windows.h>
+#include <time.h>
+#include <commctrl.h>
+
+#include <string>
+#include <vector>
+#include <regex>
+#include <map>
+
+#include <newpluginapi.h>
+
+#include <m_protoint.h>
+#include <m_protomod.h>
+#include <m_protosvc.h>
+
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_clist.h>
+#include <m_options.h>
+#include <m_netlib.h>
+#include <m_popup.h>
+#include <m_icolib.h>
+#include <m_userinfo.h>
+#include <m_addcontact.h>
+#include <m_message.h>
+#include <m_avatars.h>
+#include <m_skin.h>
+#include <m_chat.h>
+#include <m_genmenu.h>
+#include <m_clc.h>
+#include <m_clistint.h>
+#include <m_string.h>
+#include <m_json.h>
+#include <m_timezones.h>
+
+struct CSkypeProto;
+
+#include "version.h"
+#include "resource.h"
+#include "skype_icons.h"
+#include "skype_menus.h"
+#include "http_request.h"
+#include "requests\login.h"
+#include "requests\logout.h"
+#include "request_queue.h"
+#include "skype_proto.h"
+
+extern HINSTANCE g_hInstance;
+
+#define MODULE "SKYPE"
+
+#define SKYPE_SETTINGS_ID "Login"
+#define SKYPE_SETTINGS_PASSWORD "Password"
+#define SKYPE_SETTINGS_GROUP "DefaultGroup"
+
+
+#endif //_COMMON_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/http_request.h b/protocols/SkypeWeb/src/http_request.h
new file mode 100644
index 0000000000..40edf6895d
--- /dev/null
+++ b/protocols/SkypeWeb/src/http_request.h
@@ -0,0 +1,83 @@
+#ifndef _HTTP_REQUEST_H_
+#define _HTTP_REQUEST_H_
+
+class HttpRequest : protected NETLIBHTTPREQUEST, public MZeroedObject
+{
+protected:
+ CMStringA url;
+
+ HttpRequest()
+ {
+ cbSize = sizeof(NETLIBHTTPREQUEST);
+ }
+
+ HttpRequest(int httpMethod, LPCSTR urlFormat, va_list args)
+ {
+ this->HttpRequest::HttpRequest();
+
+ requestType = httpMethod;
+ flags = NLHRF_HTTP11 | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
+
+ url.AppendFormatV(urlFormat, args);
+ szUrl = url.GetBuffer();
+ }
+
+ void AddHeader(LPCSTR szName, LPCSTR szValue)
+ {
+ headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1));
+ headers[headersCount].szName = mir_strdup(szName);
+ headers[headersCount].szValue = mir_strdup(szValue);
+ headersCount++;
+ }
+
+ void SetData(const char *data, size_t size)
+ {
+ if (pData != NULL)
+ mir_free(pData);
+
+ dataLength = (int)size;
+ pData = (char*)mir_alloc(size + 1);
+ memcpy(pData, data, size);
+ pData[size] = 0;
+ }
+
+public:
+ HttpRequest(int type, LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(type, urlFormat, args);
+ va_end(args);
+ }
+
+ ~HttpRequest()
+ {
+ for (int i = 0; i < headersCount; i++)
+ {
+ mir_free(headers[i].szName);
+ mir_free(headers[i].szValue);
+ }
+ mir_free(headers);
+ mir_free(pData);
+ }
+
+ void SetCookie(LPCSTR szValue)
+ {
+ AddHeader("Set-Cookie", szValue);
+ }
+
+ NETLIBHTTPREQUEST * Send(HANDLE hConnection)
+ {
+ if (url.Find("http", 0) != 0)
+ url.Insert(0, flags & NLHRF_SSL ? "https://" : "http://");
+ szUrl = url.GetBuffer();
+
+ char message[1024];
+ mir_snprintf(message, SIZEOF(message), "Send request to %s", szUrl);
+ CallService(MS_NETLIB_LOG, (WPARAM)hConnection, (LPARAM)&message);
+
+ return (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hConnection, (LPARAM)this);
+ }
+};
+
+#endif //_HTTP_REQUEST_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/main.cpp b/protocols/SkypeWeb/src/main.cpp
new file mode 100644
index 0000000000..6d64d7b58a
--- /dev/null
+++ b/protocols/SkypeWeb/src/main.cpp
@@ -0,0 +1,62 @@
+#include "common.h"
+
+int hLangpack;
+TIME_API tmi = { 0 };
+HINSTANCE g_hInstance;
+
+PLUGININFOEX pluginInfo =
+{
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESCRIPTION,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ // {57E90AC6-1067-423B-8CA3-70A39D200D4F}
+ { 0x57e90ac6, 0x1067, 0x423b, {0x8c, 0xa3, 0x70, 0xa3, 0x9d, 0x20, 0xd, 0x4f}}
+};
+
+DWORD WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID)
+{
+ g_hInstance = hInstance;
+
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD)
+{
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST};
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+ mir_getTMI(&tmi);
+ mir_getLP(&pluginInfo);
+
+ PROTOCOLDESCRIPTOR pd = { sizeof(pd) };
+ pd.szName = MODULE;
+ pd.type = PROTOTYPE_PROTOCOL;
+ pd.fnInit = (pfnInitProto)CSkypeProto::InitAccount;
+ pd.fnUninit = (pfnUninitProto)CSkypeProto::UninitAccount;
+ CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd);
+
+ CSkypeProto::InitIcons();
+ CSkypeProto::InitMenus();
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, &CSkypeProto::OnModulesLoaded);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ CSkypeProto::UninitIcons();
+ CSkypeProto::UninitMenus();
+
+ return 0;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/request_queue.cpp b/protocols/SkypeWeb/src/request_queue.cpp
new file mode 100644
index 0000000000..6448186614
--- /dev/null
+++ b/protocols/SkypeWeb/src/request_queue.cpp
@@ -0,0 +1,88 @@
+#include "common.h"
+
+RequestQueue::RequestQueue(HANDLE hConnection) :
+ hConnection(hConnection), requests(1)
+{
+ hRequestQueueThread = NULL;
+ hRequestQueueEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+}
+
+RequestQueue::~RequestQueue()
+{
+ requests.destroy();
+ CloseHandle(hRequestQueueEvent);
+}
+
+void RequestQueue::Start()
+{
+ if (!isTerminated)
+ return;
+
+ isTerminated = false;
+ if (hRequestQueueThread == NULL)
+ {
+ hRequestQueueThread = mir_forkthread((pThreadFunc)&RequestQueue::WorkerThread, this);
+ }
+}
+
+void RequestQueue::Stop()
+{
+ if (isTerminated)
+ return;
+
+ isTerminated = true;
+ hRequestQueueThread = NULL;
+}
+
+void RequestQueue::Push(HttpRequest *request, HttpResponseCallback response, void *arg)
+{
+ if (isTerminated)
+ return;
+
+ RequestQueueItem *item = new RequestQueueItem(request, response, arg);
+ {
+ mir_cslock lock(requestQueueLock);
+
+ requests.insert(item);
+ }
+ SetEvent(hRequestQueueEvent);
+}
+
+void RequestQueue::Execute(RequestQueueItem *item)
+{
+ NETLIBHTTPREQUEST *response = item->request->Send(hConnection);
+ if (item->responseCallback != NULL)
+ {
+ item->responseCallback(response, item->arg);
+ }
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response);
+ requests.remove(item);
+ delete item;
+}
+
+unsigned int RequestQueue::WorkerThread(void* owner, void*)
+{
+ RequestQueue *that = (RequestQueue*)owner;
+
+ while (!that->isTerminated)
+ {
+ WaitForSingleObject(that->hRequestQueueEvent, INFINITE);
+ while (true)
+ {
+ RequestQueueItem *item = NULL;
+ {
+ mir_cslock lock(that->requestQueueLock);
+
+ if (that->requests.getCount() == 0)
+ break;
+
+ item = that->requests[0];
+ that->requests.remove(0);
+ }
+ if (item != NULL)
+ that->Execute(item);
+ }
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/request_queue.h b/protocols/SkypeWeb/src/request_queue.h
new file mode 100644
index 0000000000..df9154882c
--- /dev/null
+++ b/protocols/SkypeWeb/src/request_queue.h
@@ -0,0 +1,50 @@
+#ifndef _SKYPE_REQUEST_QUEUE_H_
+#define _SKYPE_REQUEST_QUEUE_H_
+
+typedef void (*HttpResponseCallback)(const NETLIBHTTPREQUEST *response, void *arg);
+
+struct RequestQueueItem
+{
+ void *arg;
+ HttpRequest *request;
+ HttpResponseCallback responseCallback;
+
+ RequestQueueItem(HttpRequest *request, void *arg) :
+ request(request), responseCallback(NULL), arg(arg) { }
+
+ RequestQueueItem(HttpRequest *request, HttpResponseCallback response, void *arg) :
+ request(request), responseCallback(response), arg(arg) { }
+
+ ~RequestQueueItem()
+ {
+ delete request;
+ request = NULL;
+ responseCallback = NULL;
+ }
+};
+
+class RequestQueue
+{
+private:
+ bool isTerminated;
+ HANDLE hConnection;
+ mir_cs requestQueueLock;
+ LIST<RequestQueueItem> requests;
+ HANDLE hRequestQueueEvent, hRequestQueueThread;
+
+ void Execute(RequestQueueItem *item);
+
+ static unsigned int __cdecl WorkerThread(void*, void*);
+
+public:
+ RequestQueue(HANDLE hConnection);
+ ~RequestQueue();
+
+ void Start();
+ void Stop();
+
+ void Push(HttpRequest *request, HttpResponseCallback response = NULL, void *arg = NULL);
+
+};
+
+#endif //_SKYPE_REQUEST_QUEUE_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/requests/login.h b/protocols/SkypeWeb/src/requests/login.h
new file mode 100644
index 0000000000..e1d94806b7
--- /dev/null
+++ b/protocols/SkypeWeb/src/requests/login.h
@@ -0,0 +1,44 @@
+#ifndef _SKYPE_REQUEST_LOGIN_H_
+#define _SKYPE_REQUEST_LOGIN_H_
+
+class LoginRequest : public HttpRequest
+{
+public:
+ LoginRequest() :
+ HttpRequest(REQUEST_POST, "login.skype.com/login")
+ {
+ flags |= NLHRF_SSL;
+
+ url.Append("?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com");
+ }
+
+ LoginRequest(const char *username, const char *password, const char *pie, const char *etm) :
+ HttpRequest(REQUEST_POST, "login.skype.com/login")
+ {
+ flags |= NLHRF_SSL;
+
+ url.Append("?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com");
+
+ LPTIME_ZONE_INFORMATION tzi = tmi.getTziByContact(NULL);
+
+ char sign = tzi->Bias > 0 ? '-' : '+';
+ int hours = tzi->Bias / -60;
+ int minutes = tzi->Bias % -60;
+
+ CMStringA data = "";
+ data.AppendFormat("username=%s&", username);
+ data.AppendFormat("password=%s&", password);
+ data.AppendFormat("pie=%s&", ptrA(mir_urlEncode(pie)));
+ data.AppendFormat("etm=%s&", ptrA(mir_urlEncode(etm)));
+ data.AppendFormat("timezone_field=%c%02d|%02d&", sign, hours, minutes);
+ data.AppendFormat("js_time=%d.00&", time(NULL));
+ data.Append("client_id=578134&");
+ data.Append("redirect_uri=https%3A%2F%2Fweb.skype.com");
+
+ SetData(data, data.GetLength());
+
+ AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ }
+};
+
+#endif //_SKYPE_REQUEST_LOGIN_H_
diff --git a/protocols/SkypeWeb/src/requests/logout.h b/protocols/SkypeWeb/src/requests/logout.h
new file mode 100644
index 0000000000..60f30e639c
--- /dev/null
+++ b/protocols/SkypeWeb/src/requests/logout.h
@@ -0,0 +1,13 @@
+#ifndef _SKYPE_REQUEST_LOGOUT_H_
+#define _SKYPE_REQUEST_LOGOUT_H_
+
+class LogoutRequest : public HttpRequest
+{
+public:
+ LogoutRequest() : HttpRequest(REQUEST_POST, "login.skype.com/logout")
+ {
+ flags |= NLHRF_SSL;
+ }
+};
+
+#endif //_SKYPE_REQUEST_LOGOUT_H_
diff --git a/protocols/SkypeWeb/src/resource.h b/protocols/SkypeWeb/src/resource.h
new file mode 100644
index 0000000000..bbd89be4de
--- /dev/null
+++ b/protocols/SkypeWeb/src/resource.h
@@ -0,0 +1,23 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by E:\Projects\C++\MirandaNG\protocols\SkypeWeb\res\resource.rc
+//
+#define IDC_LOGIN 101
+#define IDC_PASSWORD 102
+#define IDD_ACCOUNT_MANAGER 103
+#define IDD_OPTIONS_MAIN 104
+#define IDI_SKYPE 105
+#define IDC_GROUP 106
+#define IDD_PASSWORD_EDITOR 107
+#define IDC_SAVEPERMANENTLY 108
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 109
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1026
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/protocols/SkypeWeb/src/skype_accounts.cpp b/protocols/SkypeWeb/src/skype_accounts.cpp
new file mode 100644
index 0000000000..4b1ae6d536
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_accounts.cpp
@@ -0,0 +1,51 @@
+#include "common.h"
+
+LIST<CSkypeProto> CSkypeProto::Accounts(1, CSkypeProto::CompareAccounts);
+
+int CSkypeProto::CompareAccounts(const CSkypeProto *p1, const CSkypeProto *p2)
+{
+ return _tcscmp(p1->m_tszUserName, p2->m_tszUserName);
+}
+
+CSkypeProto* CSkypeProto::InitAccount(const char *protoName, const wchar_t *userName)
+{
+ CSkypeProto *proto = new CSkypeProto(protoName, userName);
+ Accounts.insert(proto);
+ return proto;
+}
+
+int CSkypeProto::UninitAccount(CSkypeProto *proto)
+{
+ Accounts.remove(proto);
+ delete proto;
+ return 0;
+}
+
+CSkypeProto* CSkypeProto::GetContactAccount(MCONTACT hContact)
+{
+ for (int i = 0; i < Accounts.getCount(); i++)
+ {
+ if (mir_strcmpi(GetContactProto(hContact), Accounts[i]->m_szModuleName) == 0)
+ {
+ return Accounts[i];
+ }
+ }
+ return NULL;
+}
+
+int CSkypeProto::OnAccountLoaded(WPARAM, LPARAM)
+{
+ HookProtoEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit);
+
+ return 0;
+}
+
+INT_PTR CSkypeProto::OnAccountManagerInit(WPARAM, LPARAM lParam)
+{
+ return (INT_PTR)CreateDialogParam(
+ g_hInstance,
+ MAKEINTRESOURCE(IDD_ACCOUNT_MANAGER),
+ (HWND)lParam,
+ CSkypeProto::MainOptionsProc,
+ (LPARAM)this);
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp
new file mode 100644
index 0000000000..c8aea263e5
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_contacts.cpp
@@ -0,0 +1,103 @@
+#include "common.h"
+
+WORD CSkypeProto::GetContactStatus(MCONTACT hContact)
+{
+ return getWord(hContact, "Status", ID_STATUS_OFFLINE);
+}
+
+void CSkypeProto::SetContactStatus(MCONTACT hContact, WORD status)
+{
+ WORD oldStatus = GetContactStatus(hContact);
+ if (oldStatus != status)
+ {
+ setWord(hContact, "Status", status);
+ }
+}
+
+void CSkypeProto::SetAllContactsStatus(WORD status)
+{
+ for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
+ {
+ SetContactStatus(hContact, status);
+ }
+}
+
+MCONTACT CSkypeProto::GetContactFromAuthEvent(MEVENT hEvent)
+{
+ DWORD body[3];
+ DBEVENTINFO dbei = { sizeof(DBEVENTINFO) };
+ dbei.cbBlob = sizeof(DWORD) * 2;
+ dbei.pBlob = (PBYTE)&body;
+
+ if (db_event_get(hEvent, &dbei))
+ return INVALID_CONTACT_ID;
+
+ if (dbei.eventType != EVENTTYPE_AUTHREQUEST)
+ return INVALID_CONTACT_ID;
+
+ if (strcmp(dbei.szModule, m_szModuleName) != 0)
+ return INVALID_CONTACT_ID;
+
+ return DbGetAuthEventContact(&dbei);
+}
+
+MCONTACT CSkypeProto::GetContact(const char *login)
+{
+ MCONTACT hContact = NULL;
+ for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
+ {
+ ptrA contactLogin(getStringA(hContact, SKYPE_SETTINGS_ID));
+ if (mir_strcmpi(login, contactLogin) == 0)
+ {
+ break;
+ }
+ }
+ return hContact;
+}
+
+MCONTACT CSkypeProto::AddContact(const char *login, bool isTemporary)
+{
+ MCONTACT hContact = GetContact(login);
+ if (!hContact)
+ {
+ hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName);
+
+ setString(hContact, SKYPE_SETTINGS_ID, login);
+
+ DBVARIANT dbv;
+ if (!getTString(SKYPE_SETTINGS_GROUP, &dbv))
+ {
+ db_set_ts(hContact, "CList", "Group", dbv.ptszVal);
+ db_free(&dbv);
+ }
+
+ setByte(hContact, "Auth", 1);
+ setByte(hContact, "Grant", 1);
+
+ if (isTemporary)
+ {
+ db_set_b(hContact, "CList", "NotOnList", 1);
+ }
+ }
+ return hContact;
+}
+
+void CSkypeProto::LoadFriendList(void*)
+{
+}
+
+INT_PTR CSkypeProto::OnRequestAuth(WPARAM hContact, LPARAM lParam)
+{
+ return 0;
+}
+
+INT_PTR CSkypeProto::OnGrantAuth(WPARAM hContact, LPARAM)
+{
+ return 0;
+}
+
+int CSkypeProto::OnContactDeleted(MCONTACT hContact, LPARAM)
+{
+ return 0;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp
new file mode 100644
index 0000000000..c4655bd310
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_events.cpp
@@ -0,0 +1,93 @@
+#include "common.h"
+
+int CSkypeProto::OnModulesLoaded(WPARAM, LPARAM)
+{
+ return 0;
+}
+
+void CSkypeProto::OnLoginFirst(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex;
+ std::smatch match;
+
+ const std::string content = response->pData;
+
+ regex = "<input type=\"hidden\" name=\"pie\" id=\"pie\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string pie = match[1];
+
+ regex = "<input type=\"hidden\" name=\"etm\" id=\"etm\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string etm = match[1];
+
+ ptrA login(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_ID))));
+ ptrA password(mir_utf8encodeT(ptrT(getTStringA(SKYPE_SETTINGS_PASSWORD))));
+
+ requestQueue->Push(new LoginRequest(login, password, pie.c_str(), etm.c_str()), HttpResponse<&CSkypeProto::OnLoginSecond>, this);
+}
+
+void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response)
+{
+ if (response == NULL)
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex;
+ std::smatch match;
+
+ std::string content = response->pData;
+
+ regex = "<input type=\"hidden\" name=\"skypetoken\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string token = match[1];
+ setString("TokenSecret", token.c_str());
+
+ regex = "<input type=\"hidden\" name=\"expires_in\" value=\"(.+?)\"/>";
+ if (!std::regex_search(content, match, regex))
+ {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, (HANDLE)NULL, 1001);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string expiresIn = match[1];
+ int seconds = atoi(expiresIn.c_str());
+ setDword("TokenExpiresIn", time(NULL) + seconds);
+
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ regex = "^(.+?)=(.+?);";
+ content = response->headers[i].szValue;
+
+ if (std::regex_search(content, match, regex))
+ cookies[match[1]] = match[2];
+ }
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus);
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_icons.cpp b/protocols/SkypeWeb/src/skype_icons.cpp
new file mode 100644
index 0000000000..8f5fc273e1
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_icons.cpp
@@ -0,0 +1,63 @@
+#include "common.h"
+
+IconInfo CSkypeProto::Icons[] =
+{
+ { LPGENT("Protocol icon"), "main", IDI_SKYPE },
+};
+
+void CSkypeProto::InitIcons()
+{
+ TCHAR szFile[MAX_PATH];
+ GetModuleFileName(g_hInstance, szFile, MAX_PATH);
+
+ char szSettingName[100];
+ TCHAR szSectionName[100];
+
+ SKINICONDESC sid = { sizeof(SKINICONDESC) };
+ sid.flags = SIDF_ALL_TCHAR;
+ sid.ptszDefaultFile = szFile;
+ sid.pszName = szSettingName;
+ sid.ptszSection = szSectionName;
+
+ mir_sntprintf(szSectionName, SIZEOF(szSectionName), _T("%s/%s"), LPGENT("Protocols"), LPGENT(MODULE));
+ for (int i = 0; i < SIZEOF(Icons); i++)
+ {
+ mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", MODULE, Icons[i].Name);
+
+ sid.ptszDescription = Icons[i].Description;
+ sid.iDefaultIndex = -Icons[i].IconId;
+ Icons[i].Handle = Skin_AddIcon(&sid);
+ }
+}
+
+HANDLE CSkypeProto::GetIconHandle(const char *name)
+{
+ for (size_t i = 0; i < SIZEOF(Icons); i++)
+ {
+ if (mir_strcmpi(Icons[i].Name, name) == 0)
+ {
+ return Icons[i].Handle;
+ }
+ }
+ return 0;
+}
+
+HANDLE CSkypeProto::GetSkinIconHandle(const char *name)
+{
+ char iconName[100];
+ mir_snprintf(iconName, SIZEOF(iconName), "%s_%s", MODULE, name);
+ HANDLE hIcon = Skin_GetIconHandle(iconName);
+ if (hIcon == NULL)
+ {
+ hIcon = GetIconHandle(name);
+ }
+ return hIcon;
+}
+
+void CSkypeProto::UninitIcons()
+{
+ for (size_t i = 0; i < SIZEOF(Icons); i++)
+ {
+ Skin_RemoveIcon(Icons[i].Name);
+ }
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_icons.h b/protocols/SkypeWeb/src/skype_icons.h
new file mode 100644
index 0000000000..f2bd6e0747
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_icons.h
@@ -0,0 +1,12 @@
+#ifndef _SKYPE_ICONS_H_
+#define _SKYPE_ICONS_H_
+
+struct IconInfo
+{
+ TCHAR *Description;
+ char *Name;
+ int IconId;
+ HANDLE Handle;
+};
+
+#endif //_SKYPE_ICONS_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_menus.cpp b/protocols/SkypeWeb/src/skype_menus.cpp
new file mode 100644
index 0000000000..cd38b5a4c5
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_menus.cpp
@@ -0,0 +1,97 @@
+#include "common.h"
+
+HGENMENU CSkypeProto::ContactMenuItems[CMI_MAX];
+
+int CSkypeProto::OnPrebuildContactMenu(WPARAM hContact, LPARAM)
+{
+ if (!hContact)
+ return 0;
+
+ if (m_iStatus < ID_STATUS_ONLINE)
+ return 0;
+
+ if (this->isChatRoom(hContact))
+ return 0;
+
+ bool isCtrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ bool isAuthNeed = getByte(hContact, "Auth", 0) > 0;
+ bool isGrantNeed = getByte(hContact, "Grant", 0) > 0;
+
+ Menu_ShowItem(ContactMenuItems[CMI_AUTH_REQUEST], isCtrlPressed || isAuthNeed);
+ Menu_ShowItem(ContactMenuItems[CMI_AUTH_GRANT], isCtrlPressed || isGrantNeed);
+
+ return 0;
+}
+
+int CSkypeProto::PrebuildContactMenu(WPARAM hContact, LPARAM lParam)
+{
+ for (int i = 0; i < SIZEOF(ContactMenuItems); i++)
+ {
+ Menu_ShowItem(ContactMenuItems[i], false);
+ }
+ CSkypeProto *proto = CSkypeProto::GetContactAccount(hContact);
+ return proto ? proto->OnPrebuildContactMenu(hContact, lParam) : 0;
+}
+
+void CSkypeProto::InitMenus()
+{
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU, &CSkypeProto::PrebuildContactMenu);
+
+ //hChooserMenu = MO_CreateMenuObject("SkypeAccountChooser", LPGEN("Skype menu chooser"), 0, "Skype/MenuChoose");
+
+ CLISTMENUITEM mi = { sizeof(CLISTMENUITEM) };
+ mi.flags = CMIF_TCHAR;
+
+ // Request authorization
+ mi.pszService = MODULE"/RequestAuth";
+ mi.ptszName = LPGENT("Request authorization");
+ mi.position = CMI_POSITION + CMI_AUTH_REQUEST;
+ mi.icolibItem = LoadSkinnedIconHandle(SKINICON_AUTH_REQUEST);
+ ContactMenuItems[CMI_AUTH_REQUEST] = Menu_AddContactMenuItem(&mi);
+ CreateServiceFunction(mi.pszService, GlobalService<&CSkypeProto::OnRequestAuth>);
+
+ // Grant authorization
+ mi.pszService = MODULE"/GrantAuth";
+ mi.ptszName = LPGENT("Grant authorization");
+ mi.position = CMI_POSITION + CMI_AUTH_GRANT;
+ mi.icolibItem = LoadSkinnedIconHandle(SKINICON_AUTH_GRANT);
+ ContactMenuItems[CMI_AUTH_GRANT] = Menu_AddContactMenuItem(&mi);
+ CreateServiceFunction(mi.pszService, GlobalService<&CSkypeProto::OnGrantAuth>);
+}
+
+void CSkypeProto::UninitMenus()
+{
+}
+
+
+int CSkypeProto::OnInitStatusMenu()
+{
+ char text[MAX_PATH];
+ mir_strcpy(text, m_szModuleName);
+ char *tDest = text + strlen(text);
+
+ CLISTMENUITEM mi = { sizeof(mi) };
+ mi.pszService = text;
+
+ HGENMENU hStatusMunuRoot = MO_GetProtoRootMenu(m_szModuleName);
+ if (!hStatusMunuRoot)
+ {
+ mi.ptszName = m_tszUserName;
+ mi.position = -1999901006;
+ mi.hParentMenu = HGENMENU_ROOT;
+ mi.flags = CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED;
+ mi.icolibItem = GetSkinIconHandle("main");
+ hStatusMunuRoot = /*m_hMenuRoot = */Menu_AddProtoMenuItem(&mi);
+ }
+ /*else
+ {
+ if (m_hMenuRoot)
+ CallService(MO_REMOVEMENUITEM, (WPARAM)m_hMenuRoot, 0);
+ m_hMenuRoot = NULL;
+ }*/
+
+ mi.hParentMenu = hStatusMunuRoot;
+ mi.flags = CMIF_CHILDPOPUP | CMIF_TCHAR;
+
+ return 0;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_menus.h b/protocols/SkypeWeb/src/skype_menus.h
new file mode 100644
index 0000000000..6930ddeb2f
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_menus.h
@@ -0,0 +1,11 @@
+#ifndef _SKYPE_MENUS_H_
+#define _SKYPE_MENUS_H_
+
+#define CMI_POSITION -201001000
+#define CMI_AUTH_REQUEST 1
+#define CMI_AUTH_GRANT 2
+#define CMI_MAX 3 // this item shall be the last one
+
+#define SMI_POSITION 200000
+
+#endif //_SKYPE_MENUS_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp
new file mode 100644
index 0000000000..1fee5e1fa9
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_messages.cpp
@@ -0,0 +1,29 @@
+#include "common.h"
+
+/* MESSAGE RECEIVING */
+
+// writing message/even into db
+int CSkypeProto::OnReceiveMessage(MCONTACT hContact, PROTORECVEVENT *pre)
+{
+ //return Proto_RecvMessage(hContact, pre);
+ if (pre->szMessage == NULL)
+ return NULL;
+
+ DBEVENTINFO dbei = { sizeof(dbei) };
+ dbei.szModule = GetContactProto(hContact);
+ dbei.timestamp = pre->timestamp;
+ dbei.flags = DBEF_UTF;
+ dbei.eventType = pre->lParam;
+ dbei.cbBlob = (DWORD)strlen(pre->szMessage) + 1;
+ dbei.pBlob = (PBYTE)pre->szMessage;
+
+ return (INT_PTR)db_event_add(hContact, &dbei);
+}
+
+/* MESSAGE SENDING */
+
+// outcoming message flow
+int CSkypeProto::OnSendMessage(MCONTACT hContact, int flags, const char *szMessage)
+{
+ return 0;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_options.cpp b/protocols/SkypeWeb/src/skype_options.cpp
new file mode 100644
index 0000000000..bf5c2901f3
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_options.cpp
@@ -0,0 +1,96 @@
+#include "common.h"
+
+INT_PTR CSkypeProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CSkypeProto *proto = (CSkypeProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwnd);
+ {
+ proto = (CSkypeProto*)lParam;
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
+
+ ptrA login(proto->getStringA(SKYPE_SETTINGS_ID));
+ SetDlgItemTextA(hwnd, IDC_LOGIN, login);
+ SendDlgItemMessage(hwnd, IDC_LOGIN, EM_LIMITTEXT, 32, 0);
+
+ ptrA password(proto->getStringA("Password"));
+ SetDlgItemTextA(hwnd, IDC_PASSWORD, password);
+ SendDlgItemMessage(hwnd, IDC_PASSWORD, EM_LIMITTEXT, 20, 0);
+
+ ptrT group(proto->getTStringA(SKYPE_SETTINGS_GROUP));
+ SetDlgItemText(hwnd, IDC_GROUP, group ? group : _T("Skype"));
+ SendDlgItemMessage(hwnd, IDC_GROUP, EM_LIMITTEXT, 64, 0);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_LOGIN:
+ case IDC_GROUP:
+ case IDC_PASSWORD:
+ if ((HWND)lParam == GetFocus())
+ {
+ if (HIWORD(wParam) != EN_CHANGE) return 0;
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((NMHDR*)lParam)->code == PSN_APPLY)
+ {
+ char login[32];
+ GetDlgItemTextA(hwnd, IDC_LOGIN, login, SIZEOF(login));
+ proto->setString(SKYPE_SETTINGS_ID, login);
+
+ char password[20];
+ GetDlgItemTextA(hwnd, IDC_PASSWORD, password, SIZEOF(password));
+ proto->setString(SKYPE_SETTINGS_PASSWORD, password);
+
+ TCHAR group[64];
+ GetDlgItemText(hwnd, IDC_GROUP, group, SIZEOF(group));
+ if (_tcslen(group) > 0)
+ {
+ proto->setTString(SKYPE_SETTINGS_GROUP, group);
+ Clist_CreateGroup(0, group);
+ }
+ else
+ {
+ proto->delSetting(NULL, SKYPE_SETTINGS_GROUP);
+ }
+
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+int CSkypeProto::OnOptionsInit(WPARAM wParam, LPARAM)
+{
+ char *title = mir_t2a(m_tszUserName);
+
+ OPTIONSDIALOGPAGE odp = { sizeof(odp) };
+ odp.hInstance = g_hInstance;
+ odp.pszTitle = title;
+ odp.dwInitParam = (LPARAM)this;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.pszGroup = LPGEN("Network");
+
+ odp.pszTab = LPGEN("Account");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_MAIN);
+ odp.pfnDlgProc = MainOptionsProc;
+ Options_AddPage(wParam, &odp);
+
+ mir_free(title);
+
+ return 0;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
new file mode 100644
index 0000000000..1eddc4c2b8
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -0,0 +1,174 @@
+#include "common.h"
+
+CSkypeProto::CSkypeProto(const char* protoName, const TCHAR* userName) :
+ PROTO<CSkypeProto>(protoName, userName), password(NULL)
+{
+ m_hProtoIcon = Icons[0].Handle;
+ SetAllContactsStatus(ID_STATUS_OFFLINE);
+
+ wchar_t name[128];
+ mir_sntprintf(name, SIZEOF(name), TranslateT("%s connection"), m_tszUserName);
+ NETLIBUSER nlu = { 0 };
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE;
+ nlu.ptszDescriptiveName = name;
+ nlu.szSettingsModule = m_szModuleName;
+ m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+ requestQueue = new RequestQueue(m_hNetlibUser);
+
+ CreateProtoService(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit);
+}
+
+CSkypeProto::~CSkypeProto()
+{
+ delete requestQueue;
+ Netlib_CloseHandle(m_hNetlibUser);
+ m_hNetlibUser = NULL;
+}
+
+DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT)
+{
+ switch (type)
+ {
+ case PFLAGNUM_1:
+ return 0;
+ case PFLAGNUM_2:
+ return PF2_ONLINE;
+ case PFLAGNUM_3:
+ return PF2_ONLINE;
+ case PFLAG_UNIQUEIDTEXT:
+ return (INT_PTR)"Login";
+ case PFLAG_UNIQUEIDSETTING:
+ return (DWORD_PTR)SKYPE_SETTINGS_ID;
+ }
+
+ return 0;
+}
+
+MCONTACT CSkypeProto::AddToList(int flags, PROTOSEARCHRESULT *psr) { return 0; }
+
+MCONTACT CSkypeProto::AddToListByEvent(int, int, MEVENT) { return 0; }
+
+int CSkypeProto::Authorize(MEVENT hDbEvent) { return 0; }
+
+int CSkypeProto::AuthDeny(MEVENT, const PROTOCHAR*) { return 0; }
+
+int CSkypeProto::AuthRecv(MCONTACT, PROTORECVEVENT* pre) { return 0; }
+
+int CSkypeProto::AuthRequest(MCONTACT hContact, const PROTOCHAR *szMessage) { return 0; }
+
+HANDLE CSkypeProto::ChangeInfo(int, void*) { return 0; }
+
+HANDLE CSkypeProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* tszPath) { return 0; }
+
+int CSkypeProto::FileCancel(MCONTACT hContact, HANDLE hTransfer) { return 0; }
+
+int CSkypeProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* tszReason) { return 0; }
+
+int CSkypeProto::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** tszFilename) { return 0; }
+
+int CSkypeProto::GetInfo(MCONTACT, int) { return 0; }
+
+HANDLE CSkypeProto::SearchBasic(const PROTOCHAR*) { return 0; }
+
+HANDLE CSkypeProto::SearchByEmail(const PROTOCHAR*) { return 0; }
+
+HANDLE CSkypeProto::SearchByName(const PROTOCHAR*, const PROTOCHAR*, const PROTOCHAR*) { return 0; }
+
+HWND CSkypeProto::SearchAdvanced(HWND owner) { return 0; }
+
+HWND CSkypeProto::CreateExtendedSearchUI(HWND owner) { return 0; }
+
+int CSkypeProto::RecvContacts(MCONTACT, PROTORECVEVENT*) { return 0; }
+
+int CSkypeProto::RecvFile(MCONTACT hContact, PROTOFILEEVENT *pre) { return 0; }
+
+int CSkypeProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) { return 0; }
+
+int CSkypeProto::RecvUrl(MCONTACT, PROTORECVEVENT*) { return 0; }
+
+int CSkypeProto::SendContacts(MCONTACT, int, int, MCONTACT*) { return 0; }
+
+HANDLE CSkypeProto::SendFile(MCONTACT hContact, const PROTOCHAR *szDescription, PROTOCHAR **ppszFiles) { return 0; }
+
+int CSkypeProto::SendMsg(MCONTACT hContact, int flags, const char *msg) { return 0; }
+
+int CSkypeProto::SendUrl(MCONTACT, int, const char*) { return 0; }
+
+int CSkypeProto::SetApparentMode(MCONTACT, int) { return 0; }
+
+int CSkypeProto::SetStatus(int iNewStatus)
+{
+ if (iNewStatus == m_iDesiredStatus)
+ {
+ return 0;
+ }
+
+ debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus);
+
+ int old_status = m_iStatus;
+ m_iDesiredStatus = iNewStatus;
+
+ if (iNewStatus == ID_STATUS_OFFLINE)
+ {
+ // logout
+ PushRequest(new LogoutRequest());
+ requestQueue->Stop();
+
+ if (!Miranda_Terminated())
+ {
+ SetAllContactsStatus(ID_STATUS_OFFLINE);
+ }
+
+ m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
+ }
+ else
+ {
+ if (old_status == ID_STATUS_CONNECTING)
+ {
+ return 0;
+ }
+
+ if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE)
+ {
+ // login
+ m_iStatus = ID_STATUS_CONNECTING;
+
+ requestQueue->Start();
+ PushRequest(new LoginRequest(), HttpResponse<&CSkypeProto::OnLoginFirst>, this);
+ }
+ else
+ {
+ // set status
+ m_iStatus = iNewStatus;
+ }
+ }
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+ return 0;
+}
+
+HANDLE CSkypeProto::GetAwayMsg(MCONTACT) { return 0; }
+
+int CSkypeProto::RecvAwayMsg(MCONTACT, int, PROTORECVEVENT*) { return 0; }
+
+int CSkypeProto::SetAwayMsg(int, const PROTOCHAR *msg) { return 0; }
+
+int CSkypeProto::UserIsTyping(MCONTACT hContact, int type) { return 0; }
+
+int CSkypeProto::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam)
+{
+ switch (iEventType)
+ {
+ case EV_PROTO_ONLOAD:
+ return OnAccountLoaded(wParam, lParam);
+
+ case EV_PROTO_ONCONTACTDELETED:
+ return OnContactDeleted(wParam, lParam);
+
+ case EV_PROTO_ONMENU:
+ return OnInitStatusMenu();
+ }
+
+ return 1;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
new file mode 100644
index 0000000000..b704bd4133
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -0,0 +1,180 @@
+#ifndef _TOX_PROTO_H_
+#define _TOX_PROTO_H_
+
+class RequestQueueItem;
+
+struct CSkypeProto : public PROTO < CSkypeProto >
+{
+public:
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ //Ctors
+
+ CSkypeProto(const char *protoName, const wchar_t *userName);
+ ~CSkypeProto();
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // Virtual functions
+
+ virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT* psr);
+ virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent);
+
+ virtual int __cdecl Authorize(MEVENT hDbEvent);
+ virtual int __cdecl AuthDeny(MEVENT hDbEvent, const PROTOCHAR* szReason);
+ virtual int __cdecl AuthRecv(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage);
+
+ virtual HANDLE __cdecl ChangeInfo(int iInfoType, void* pInfoData);
+
+ virtual HANDLE __cdecl FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* tszPath);
+ virtual int __cdecl FileCancel(MCONTACT hContact, HANDLE hTransfer);
+ virtual int __cdecl FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* tszReason);
+ virtual int __cdecl FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** tszFilename);
+
+ virtual DWORD_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL);
+ virtual int __cdecl GetInfo(MCONTACT hContact, int infoType);
+
+ virtual HANDLE __cdecl SearchBasic(const PROTOCHAR* id);
+ virtual HANDLE __cdecl SearchByEmail(const PROTOCHAR* email);
+ virtual HANDLE __cdecl SearchByName(const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName);
+ virtual HWND __cdecl SearchAdvanced(HWND owner);
+ virtual HWND __cdecl CreateExtendedSearchUI(HWND owner);
+
+ virtual int __cdecl RecvContacts(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl RecvFile(MCONTACT hContact, PROTOFILEEVENT*);
+ virtual int __cdecl RecvMsg(MCONTACT hContact, PROTORECVEVENT*);
+ virtual int __cdecl RecvUrl(MCONTACT hContact, PROTORECVEVENT*);
+
+ virtual int __cdecl SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList);
+ virtual HANDLE __cdecl SendFile(MCONTACT hContact, const PROTOCHAR *szDescription, PROTOCHAR **ppszFiles);
+ virtual int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg);
+ virtual int __cdecl SendUrl(MCONTACT hContact, int flags, const char* url);
+
+ virtual int __cdecl SetApparentMode(MCONTACT hContact, int mode);
+ virtual int __cdecl SetStatus(int iNewStatus);
+
+ virtual HANDLE __cdecl GetAwayMsg(MCONTACT hContact);
+ virtual int __cdecl RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT* evt);
+ virtual int __cdecl SetAwayMsg(int iStatus, const PROTOCHAR* msg);
+
+ virtual int __cdecl UserIsTyping(MCONTACT hContact, int type);
+
+ virtual int __cdecl OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam);
+
+ // accounts
+ static CSkypeProto* InitAccount(const char *protoName, const TCHAR *userName);
+ static int UninitAccount(CSkypeProto *proto);
+
+ // icons
+ static void InitIcons();
+ static void UninitIcons();
+
+ // menus
+ static void InitMenus();
+ static void UninitMenus();
+
+ // events
+ static int OnModulesLoaded(WPARAM, LPARAM);
+
+private:
+ char *password;
+ RequestQueue *requestQueue;
+ std::map<std::string, std::string> cookies;
+
+ static INT_PTR CALLBACK PasswordEditorProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ // accounts
+ static LIST<CSkypeProto> Accounts;
+ static int CompareAccounts(const CSkypeProto *p1, const CSkypeProto *p2);
+
+ static CSkypeProto* GetContactAccount(MCONTACT hContact);
+
+ int __cdecl OnAccountLoaded(WPARAM, LPARAM);
+
+ INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM);
+
+ // api response wrappers
+ template<void(CSkypeProto::*ResponseCallback)(const NETLIBHTTPREQUEST *response)>
+ static void HttpResponse(const NETLIBHTTPREQUEST *response, void *arg)
+ {
+ (((CSkypeProto*)arg)->*ResponseCallback)(response);
+ }
+
+ template<void(CSkypeProto::*ResponseCallback)(const JSONNODE *response)>
+ static void JsonResponse(const NETLIBHTTPREQUEST *response, void *arg)
+ {
+ JSONROOT root(response->pData);
+ (((CSkypeProto*)arg)->*ResponseCallback)(root);
+ }
+
+ void PushRequest(HttpRequest *request, HttpResponseCallback response = NULL, void *arg = NULL)
+ {
+ if (!cookies.empty())
+ {
+ CMStringA allCookies;
+ for (std::map<std::string, std::string>::iterator cookie = cookies.begin(); cookie != cookies.end(); ++cookie)
+ allCookies.AppendFormat("%s=%s; ", cookie->first.c_str(), cookie->second.c_str());
+ request->SetCookie(allCookies);
+ }
+ requestQueue->Push(request, response, arg);
+ }
+
+ // icons
+ static IconInfo Icons[];
+ static HANDLE GetIconHandle(const char *name);
+ static HANDLE GetSkinIconHandle(const char *name);
+
+ // menus
+ static HGENMENU ContactMenuItems[CMI_MAX];
+ int OnPrebuildContactMenu(WPARAM hContact, LPARAM);
+ static int PrebuildContactMenu(WPARAM hContact, LPARAM lParam);
+
+ int OnInitStatusMenu();
+
+ // options
+ static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam);
+
+ // events
+ void OnLoginFirst(const NETLIBHTTPREQUEST *response);
+
+ void OnLoginSecond(const NETLIBHTTPREQUEST *response);
+
+ // contacts
+ WORD GetContactStatus(MCONTACT hContact);
+ void SetContactStatus(MCONTACT hContact, WORD status);
+ void SetAllContactsStatus(WORD status);
+
+ MCONTACT GetContact(const char *login);
+
+ MCONTACT AddContact(const char *login, bool isTemporary = false);
+
+ MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
+
+ void __cdecl LoadFriendList(void*);
+
+ INT_PTR __cdecl OnRequestAuth(WPARAM hContact, LPARAM lParam);
+ INT_PTR __cdecl OnGrantAuth(WPARAM hContact, LPARAM);
+
+ int __cdecl OnContactDeleted(MCONTACT, LPARAM);
+
+ // messages
+ int OnReceiveMessage(MCONTACT hContact, PROTORECVEVENT *pre);
+ int OnSendMessage(MCONTACT hContact, int flags, const char *message);
+
+ // utils
+ static void ShowNotification(const TCHAR *message, int flags = 0, MCONTACT hContact = NULL);
+ static void ShowNotification(const TCHAR *caption, const TCHAR *message, int flags = 0, MCONTACT hContact = NULL);
+
+ static bool IsFileExists(std::tstring path);
+
+ template<INT_PTR(__cdecl CSkypeProto::*Service)(WPARAM, LPARAM)>
+ static INT_PTR __cdecl GlobalService(WPARAM wParam, LPARAM lParam)
+ {
+ CSkypeProto *proto = CSkypeProto::GetContactAccount((MCONTACT)wParam);
+ return proto ? (proto->*Service)(wParam, lParam) : 0;
+ }
+};
+
+#endif //_TOX_PROTO_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
new file mode 100644
index 0000000000..5ce367f768
--- /dev/null
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -0,0 +1,40 @@
+#include "common.h"
+
+void CSkypeProto::ShowNotification(const TCHAR *caption, const TCHAR *message, int flags, MCONTACT hContact)
+{
+ if (Miranda_Terminated())
+ {
+ return;
+ }
+
+ if (ServiceExists(MS_POPUP_ADDPOPUPT) && db_get_b(NULL, "Popup", "ModuleIsEnabled", 1))
+ {
+ POPUPDATAT ppd = { 0 };
+ ppd.lchContact = hContact;
+ wcsncpy(ppd.lpwzContactName, caption, MAX_CONTACTNAME);
+ wcsncpy(ppd.lpwzText, message, MAX_SECONDLINE);
+ ppd.lchIcon = Skin_GetIcon("Skype_main");
+
+ if (!PUAddPopupT(&ppd))
+ return;
+ }
+
+ MessageBox(NULL, message, caption, MB_OK | flags);
+}
+
+void CSkypeProto::ShowNotification(const TCHAR *message, int flags, MCONTACT hContact)
+{
+ ShowNotification(_T(MODULE), message, flags, hContact);
+}
+
+bool CSkypeProto::IsFileExists(std::tstring path)
+{
+ WIN32_FIND_DATA wfd;
+ HANDLE hFind = FindFirstFile(path.c_str(), &wfd);
+ if (INVALID_HANDLE_VALUE != hFind)
+ {
+ FindClose(hFind);
+ return true;
+ }
+ return false;
+} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/stdafx.cpp b/protocols/SkypeWeb/src/stdafx.cpp
new file mode 100644
index 0000000000..c5fe5abaad
--- /dev/null
+++ b/protocols/SkypeWeb/src/stdafx.cpp
@@ -0,0 +1,18 @@
+/*
+Copyright (C) 2012-15 Miranda NG project (http://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 "common.h" \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/version.h b/protocols/SkypeWeb/src/version.h
new file mode 100644
index 0000000000..95bac7ffe5
--- /dev/null
+++ b/protocols/SkypeWeb/src/version.h
@@ -0,0 +1,14 @@
+#define __MAJOR_VERSION 0
+#define __MINOR_VERSION 11
+#define __RELEASE_NUM 0
+#define __BUILD_NUM 0
+
+#include <stdver.h>
+
+#define __PLUGIN_NAME "Skype protocol (Web)"
+#define __FILENAME "SkypeWeb.dll"
+#define __DESCRIPTION "Skype protocol support for Miranda NG. Based on new Skype for Web API."
+#define __AUTHOR "Miranda NG Team"
+#define __AUTHOREMAIL ""
+#define __AUTHORWEB "http://miranda-ng.org/p/SkypeWeb/"
+#define __COPYRIGHT "© 2015 Miranda NG Team"