From 3cd6cb8893596c6e07e902addec0d74c61aa3712 Mon Sep 17 00:00:00 2001 From: "jokusoftware@gmail.com" Date: Wed, 23 Nov 2011 20:28:21 +0000 Subject: latest FlashAvatars plug-in's sources: - based on Big Muscles's FlashAvatars v1.0.13.246 - added Folders plug-in support - removed STL dependency (using Miranda's core lists now), added VC6 project - added service cleanup git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@204 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- FlashAvatars/FlashAvatars.rc | 65 ++++ FlashAvatars/FlashAvatars_6.dsp | 201 +++++++++++ FlashAvatars/FlashAvatars_6.dsw | 29 ++ FlashAvatars/TigerHash.cpp | 761 ++++++++++++++++++++++++++++++++++++++++ FlashAvatars/TigerHash.h | 112 ++++++ FlashAvatars/cflash.cpp | 726 ++++++++++++++++++++++++++++++++++++++ FlashAvatars/changelog.txt | 81 +++++ FlashAvatars/criticalsection.h | 114 ++++++ FlashAvatars/resource.h | 15 + FlashAvatars/stdafx.cpp | 7 + FlashAvatars/stdafx.h | 57 +++ 11 files changed, 2168 insertions(+) create mode 100644 FlashAvatars/FlashAvatars.rc create mode 100644 FlashAvatars/FlashAvatars_6.dsp create mode 100644 FlashAvatars/FlashAvatars_6.dsw create mode 100644 FlashAvatars/TigerHash.cpp create mode 100644 FlashAvatars/TigerHash.h create mode 100644 FlashAvatars/cflash.cpp create mode 100644 FlashAvatars/changelog.txt create mode 100644 FlashAvatars/criticalsection.h create mode 100644 FlashAvatars/resource.h create mode 100644 FlashAvatars/stdafx.cpp create mode 100644 FlashAvatars/stdafx.h (limited to 'FlashAvatars') diff --git a/FlashAvatars/FlashAvatars.rc b/FlashAvatars/FlashAvatars.rc new file mode 100644 index 0000000..0fe762a --- /dev/null +++ b/FlashAvatars/FlashAvatars.rc @@ -0,0 +1,65 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,14,251 + PRODUCTVERSION 1,0,14,251 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040504b0" + BEGIN + VALUE "CompanyName", "Big Muscle" + VALUE "FileDescription", "FlashAvatars" + VALUE "FileVersion", "1, 0, 14, 251" + VALUE "InternalName", "FlashAvatars" + VALUE "LegalCopyright", "Copyright (C) 2006-2009" + VALUE "OriginalFilename", "FlashAvatars" + VALUE "ProductName", "FlashAvatars" + VALUE "ProductVersion", "1, 0, 14, 251" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x405, 1200 + END +END + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + diff --git a/FlashAvatars/FlashAvatars_6.dsp b/FlashAvatars/FlashAvatars_6.dsp new file mode 100644 index 0000000..7450308 --- /dev/null +++ b/FlashAvatars/FlashAvatars_6.dsp @@ -0,0 +1,201 @@ +# Microsoft Developer Studio Project File - Name="FlashAvatars_6" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=FlashAvatars_6 - Win32 Debug Unicode +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "FlashAvatars_6.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "FlashAvatars_6.mak" CFG="FlashAvatars_6 - Win32 Debug Unicode" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "FlashAvatars_6 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "FlashAvatars_6 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "FlashAvatars_6 - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "FlashAvatars_6 - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "FlashAvatars_6 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /I "../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /FR /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib version.lib /nologo /dll /map /debug /machine:I386 /out:"Release/FlashAvatars.dll" /ALIGN:4096 /ignore:4108 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FlashAvatars_6 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../miranda/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x25000000" /dll /map /debug /debugtype:both /machine:I386 /out:"../../bin/debug/plugins/ICQ.dll" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none /incremental:no + +!ELSEIF "$(CFG)" == "FlashAvatars_6 - Win32 Debug Unicode" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "FlashAvatars_6___Win32_Debug_Unicode" +# PROP BASE Intermediate_Dir "FlashAvatars_6___Win32_Debug_Unicode" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_Unicode" +# PROP Intermediate_Dir "Debug_Unicode" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../miranda/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../miranda/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x25000000" /dll /map /debug /debugtype:both /machine:I386 /out:"../../bin/debug/plugins/ICQ.dll" /pdbtype:sept +# SUBTRACT BASE LINK32 /pdb:none /incremental:no +# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x25000000" /dll /map /debug /debugtype:both /machine:I386 /out:"../../bin/debug Unicode/plugins/ICQ.dll" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none /incremental:no + +!ELSEIF "$(CFG)" == "FlashAvatars_6 - Win32 Release Unicode" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "FlashAvatars_6___Win32_Release_Unicode" +# PROP BASE Intermediate_Dir "FlashAvatars_6___Win32_Release_Unicode" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_Unicode" +# PROP Intermediate_Dir "Release_Unicode" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /O1 /I "../miranda/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /FR /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /Gi /GX /Zi /O1 /I "../include" /I "../ExternalAPI" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "FlashAvatars_6_EXPORTS" /FR /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x417 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /map /debug /machine:I386 /out:"../../bin/release/plugins/ICQ.dll" /ALIGN:4096 /ignore:4108 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comctl32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib version.lib /nologo /dll /map /debug /machine:I386 /out:"Release_Unicode/FlashAvatars.dll" /ALIGN:4096 /ignore:4108 +# SUBTRACT LINK32 /pdb:none /incremental:yes + +!ENDIF + +# Begin Target + +# Name "FlashAvatars_6 - Win32 Release" +# Name "FlashAvatars_6 - Win32 Debug" +# Name "FlashAvatars_6 - Win32 Debug Unicode" +# Name "FlashAvatars_6 - Win32 Release Unicode" +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\criticalsection.h +# End Source File +# Begin Source File + +SOURCE=.\m_flash.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\stdafx.h +# End Source File +# Begin Source File + +SOURCE=.\TigerHash.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\FlashAvatars.rc +# End Source File +# End Group +# Begin Source File + +SOURCE=.\cflash.cpp +# End Source File +# Begin Source File + +SOURCE=.\stdafx.cpp +# End Source File +# Begin Source File + +SOURCE=.\TigerHash.cpp +# End Source File +# End Target +# End Project diff --git a/FlashAvatars/FlashAvatars_6.dsw b/FlashAvatars/FlashAvatars_6.dsw new file mode 100644 index 0000000..471568a --- /dev/null +++ b/FlashAvatars/FlashAvatars_6.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "FlashAvatars_6"=".\FlashAvatars_6.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/FlashAvatars/TigerHash.cpp b/FlashAvatars/TigerHash.cpp new file mode 100644 index 0000000..5c680e5 --- /dev/null +++ b/FlashAvatars/TigerHash.cpp @@ -0,0 +1,761 @@ +/* + * Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "stdafx.h" +#include "TigerHash.h" + +#ifdef _WIN32 +#if defined(_M_X64) +#define TIGER_ARCH64 +#endif +#if !(defined(_M_IX86) || defined(_M_X64)) +#define TIGER_BIG_ENDIAN +#endif +#else // _WIN32 +#if defined(__x86_64__) || defined(__alpha) +#define TIGER_ARCH64 +#endif +#if !(defined(__i386__) || defined(__x86_64__) || defined(__alpha)) +#define TIGER_BIG_ENDIAN +#endif +#endif // _WIN32 + +#define PASSES 3 + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +#define save_abc \ + aa = a; \ + bb = b; \ + cc = c; + +#ifdef TIGER_ARCH64 +#define round(a,b,c,x,mul) \ + c ^= x; \ + a -= t1[((c)>>(0*8))&0xFF] ^ t2[((c)>>(2*8))&0xFF] ^ \ + t3[((c)>>(4*8))&0xFF] ^ t4[((c)>>(6*8))&0xFF] ; \ + b += t4[((c)>>(1*8))&0xFF] ^ t3[((c)>>(3*8))&0xFF] ^ \ + t2[((c)>>(5*8))&0xFF] ^ t1[((c)>>(7*8))&0xFF] ; \ + b *= mul; +#else +#define round(a,b,c,x,mul) \ + c ^= x; \ + a -= t1[(uint8_t)(c)] ^ \ + t2[(uint8_t)(((uint32_t)(c))>>(2*8))] ^ \ + t3[(uint8_t)(((uint64_t)(c))>>(4*8))] ^ \ + t4[(uint8_t)(((uint32_t)(((uint64_t)(c))>>(4*8)))>>(2*8))] ; \ + b += t4[(uint8_t)(((uint32_t)(c))>>(1*8))] ^ \ + t3[(uint8_t)(((uint32_t)(c))>>(3*8))] ^ \ + t2[(uint8_t)(((uint32_t)(((uint64_t)(c))>>(4*8)))>>(1*8))] ^ \ + t1[(uint8_t)(((uint32_t)(((uint64_t)(c))>>(4*8)))>>(3*8))]; \ + b *= mul; +#endif + +#define pass(a,b,c,mul) \ + round(a,b,c,x0,mul) \ + round(b,c,a,x1,mul) \ + round(c,a,b,x2,mul) \ + round(a,b,c,x3,mul) \ + round(b,c,a,x4,mul) \ + round(c,a,b,x5,mul) \ + round(a,b,c,x6,mul) \ + round(b,c,a,x7,mul) + +#define key_schedule \ + x0 -= x7 ^ _ULL(0xA5A5A5A5A5A5A5A5); \ + x1 ^= x0; \ + x2 += x1; \ + x3 -= x2 ^ ((~x1)<<19); \ + x4 ^= x3; \ + x5 += x4; \ + x6 -= x5 ^ ((~x4)>>23); \ + x7 ^= x6; \ + x0 += x7; \ + x1 -= x0 ^ ((~x7)<<19); \ + x2 ^= x1; \ + x3 += x2; \ + x4 -= x3 ^ ((~x2)>>23); \ + x5 ^= x4; \ + x6 += x5; \ + x7 -= x6 ^ _ULL(0x0123456789ABCDEF); + +#define feedforward \ + a ^= aa; \ + b -= bb; \ + c += cc; + +#ifdef TIGER_ARCH64 +#define compress \ + save_abc \ + pass(a,b,c,5) \ + key_schedule \ + pass(c,a,b,7) \ + key_schedule \ + pass(b,c,a,9) \ + for(pass_no=3; pass_no 0) { + size_t n = min(length, BLOCK_SIZE-tmppos); + memcpy(tmp + tmppos, str, n); + str += n; + pos += n; + length -= n; + + if((tmppos + n) == BLOCK_SIZE) { +#ifdef TIGER_BIG_ENDIAN + for(j=0; j=BLOCK_SIZE) { +#ifdef TIGER_BIG_ENDIAN + for(j=0; j (BLOCK_SIZE - sizeof(uint64_t))) { + memset(tmp + tmppos, 0, BLOCK_SIZE - tmppos); +#ifdef TIGER_BIG_ENDIAN + for(j=0; j + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#ifdef __GNUC__ +#define _ULL(x) x##ull +#else +#define _ULL(x) x +#endif + +class TigerHash { +public: + /** Hash size in bytes */ + enum { HASH_SIZE = 24 }; + + TigerHash() : pos(0) { + res[0]=_ULL(0x0123456789ABCDEF); + res[1]=_ULL(0xFEDCBA9876543210); + res[2]=_ULL(0xF096A5B4C3B2E187); + } + + ~TigerHash() { + } + + TCHAR* toBase32(TCHAR dst[((HASH_SIZE * 8) / 5) + 2]) { + const TCHAR base32Alphabet[] = _T("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"); + uint8_t hash[HASH_SIZE]; + memcpy(hash, res, HASH_SIZE); + + // Code snagged from the bitzi bitcollider + size_t i, index; + uint8_t word; + //wchar_t* dst = new wchar_t[]; + memset(dst, 0, sizeof(dst)); + + int j = 0; + for(i = 0, index = 0; i < HASH_SIZE; j++) { + /* Is the current word going to span a byte boundary? */ + if (index > 3) { + word = (uint8_t)(hash[i] & (0xFF >> index)); + index = (index + 5) % 8; + word <<= index; + if ((i + 1) < HASH_SIZE) + word |= hash[i + 1] >> (8 - index); + + i++; + } else { + word = (uint8_t)(hash[i] >> (8 - (index + 5))) & 0x1F; + index = (index + 5) % 8; + if (index == 0) + i++; + } + + //dcassert(word < 32); + dst[j] = base32Alphabet[word]; + } + dst[39] = NULL; + return dst; + } + + /** Calculates the Tiger hash of the data. */ + void update(const void* data, size_t len); + /** Call once all data has been processed. */ + uint8_t* finalize(); + +private: + enum { BLOCK_SIZE = 512/8 }; + /** 512 bit blocks for the compress function */ + uint8_t tmp[512/8]; + /** State / final hash value */ + uint64_t res[3]; + /** Total number of bytes compressed */ + uint64_t pos; + /** S boxes */ + static uint64_t table[]; + + void tigerCompress(const uint64_t* data, uint64_t state[3]); +}; + +#endif // !defined(TIGER_HASH_H) + +/** + * @file + * $Id: TigerHash.h,v 1.10 2006/10/13 20:04:32 bigmuscle Exp $ + */ diff --git a/FlashAvatars/cflash.cpp b/FlashAvatars/cflash.cpp new file mode 100644 index 0000000..2fe61dd --- /dev/null +++ b/FlashAvatars/cflash.cpp @@ -0,0 +1,726 @@ +#include "stdafx.h" + +#define MIRANDA_VER 0x0700 + +#include "m_stdhdr.h" +#include "win2k.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "m_flash.h" +#include "m_avatars.h" +#include "m_utils.h" +#include "m_netlib.h" + +#include "m_clist.h" +#include "m_clistint.h" + +#include "m_folders.h" + +#include "CriticalSection.h" +#include "TigerHash.h" + +//#import "PROGID:ShockwaveFlash.ShockwaveFlash" no_namespace +#import "Macromed\Flash\Flash10p.ocx" no_namespace exclude("IServiceProvider") + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + NULL, + PLUGIN_MAKE_VERSION(0, 0, 1, 14), + "Load and display flash avatars", + "Big Muscle", + "", + "Copyright 2000-2009 Miranda-IM project", + "http://www.miranda-im.org", + UNICODE_AWARE, + 0, + // {72765A6F-B017-42f1-B30F-5E0941273A3F} + { 0x72765a6f, 0xb017, 0x42f1, { 0xb3, 0xf, 0x5e, 0x9, 0x41, 0x27, 0x3a, 0x3f } } +}; + + +/* a strcmp() that likes NULL */ +int __fastcall strcmpnull(const char *str1, const char *str2) { + if (str1 && str2) + return strcmp(str1, str2); + + if (!str1 && !str2) + return 0; + + return 1; +} + + +struct flash_avatar_item { + HANDLE hContact; + FLASHAVATAR hFA; + IShockwaveFlash* pFlash; + + char* getProto() { return (hFA.cProto) ? hFA.cProto : (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hFA.hContact, 0); } + + __inline void* operator new(size_t size) { return mir_calloc(size); } + __inline void operator delete( void* p ) { mir_free(p); } + + flash_avatar_item(HANDLE contact, FLASHAVATAR& fa, IShockwaveFlash *flash) { hContact = contact; hFA = fa; pFlash = flash; } +}; + +static int CompareFlashItems(const flash_avatar_item* p1, const flash_avatar_item* p2) { + if (p1->hContact < p2->hContact) + return -1; + + if (p1->hContact > p2->hContact) + return 1; + + int cProto = strcmpnull(p1->hFA.cProto, p2->hFA.cProto); + if (cProto) + return cProto; + + return (p1->hFA.id > p2->hFA.id) ? -1 : (p1->hFA.id == p2->hFA.id) ? 0 : 1; +}; + +HINSTANCE g_hInst = 0; + +PLUGINLINK *pluginLink; +MM_INTERFACE mmi; +LIST_INTERFACE li; + +HANDLE hNetlibUser; + +static char pluginName[64]; + +static HANDLE hHooks[4]; +static HANDLE hServices[7]; +static CriticalSection cs; + +static HANDLE hAvatarsFolder = NULL; + +static LIST FlashList(5, CompareFlashItems); + +typedef HRESULT (WINAPI *LPAtlAxAttachControl)(IUnknown* pControl, HWND hWnd, IUnknown** ppUnkContainer); +LPAtlAxAttachControl MyAtlAxAttachControl; + + +#define getFace() \ + char* face;\ + switch (status) {\ + case ID_STATUS_OFFLINE:\ + face = AV_OFFLINE;\ + break;\ + case ID_STATUS_ONLINE:\ + case ID_STATUS_INVISIBLE:\ + face = AV_NORMAL;\ + break;\ + default:\ + face = AV_BUSY;\ + break;\ + } + +static bool DownloadFlashFile(char *url, const TCHAR* save_file, int recurse_count /*=0*/) { + if(!url || recurse_count > 5) { + return false; + } + + NETLIBHTTPREQUEST req = {0}; + req.cbSize = sizeof(req); + req.requestType = REQUEST_GET; + req.szUrl = url; + req.flags = 0;//NLHRF_HTTP11; + + NETLIBHTTPREQUEST *resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&req); + if(resp) { + if(resp->resultCode == 200) { + HANDLE hSaveFile = CreateFile(save_file, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if(hSaveFile != INVALID_HANDLE_VALUE) { + unsigned long bytes_written = 0; + if(WriteFile(hSaveFile, resp->pData, resp->dataLength, &bytes_written, NULL) == TRUE) { + CloseHandle(hSaveFile); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + return true; + } + CloseHandle(hSaveFile); + } + } else if(resp->resultCode >= 300 && resp->resultCode < 400) { + // get new location + bool ret = false; + for(int i = 0; i < resp->headersCount; i++) { + if(strcmpnull(resp->headers[i].szName, "Location") == 0) { + ret = DownloadFlashFile(resp->headers[i].szValue, save_file, recurse_count + 1); + break; + } + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + return ret; + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + resp = 0; + } + + return false; +} +/* +static wchar_t *u2w(const char *utfs) { + if(utfs) { + int size = MultiByteToWideChar(CP_UTF8, 0, utfs, -1, 0, 0); + wchar_t *buff = new wchar_t[size]; + MultiByteToWideChar(CP_UTF8, 0, utfs, -1, buff, size); + return buff; + } else + return 0; +} +*/ + +static void __cdecl loadFlash_Thread(void *p) { + debug("Avatar thread executed...\n"); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); + + flash_avatar_item* fai = (flash_avatar_item*)p; + IShockwaveFlash* flash = fai->pFlash; + + if(strchr(fai->hFA.cUrl, '?') == NULL) { + // make hash of url + debug("Making TTH hash from URL...\n"); + TigerHash th; + th.update(fai->hFA.cUrl, strlen(fai->hFA.cUrl)); + th.finalize(); + + // create local path name + TCHAR name[MAX_PATH], path[MAX_PATH]; + TCHAR tth[((TigerHash::HASH_SIZE * 8) / 5) + 2]; + FOLDERSGETDATA fgd = {0}; + + fgd.cbSize = sizeof(FOLDERSGETDATA); + fgd.nMaxPathSize = MAX_PATH; + fgd.szPathT = path; + if(!hAvatarsFolder || CallService(MS_FOLDERS_GET_PATH, (WPARAM)hAvatarsFolder, (LPARAM)&fgd)) { + if(ServiceExists(MS_UTILS_REPLACEVARS)) { + TCHAR *tmpPath = Utils_ReplaceVarsT(_T("%miranda_avatarcache%")); + mir_sntprintf(path, MAX_PATH, _T("%s\\%s"), tmpPath, _T("Flash")); + mir_free(tmpPath); + } else + CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)(_T("Flash")), (LPARAM)path); + } else { + if(_tcslen(path) && path[_tcslen(path)-1]=='\\') + path[_tcslen(path)-1] = 0; + } + + CreateDirectory(path, NULL); // create directory if it doesn't exist + _sntprintf(name, MAX_PATH, _T("%s\\%s.swf"), path, th.toBase32(tth)); + + // download remote file if it doesn't exist + if (GetFileAttributes(name) == 0xFFFFFFFF) { + debug("Downloading flash file...\n"); + DownloadFlashFile(fai->hFA.cUrl, name, 0); + } + + // load and play local flash movie + debug("Loading flash movie...\n"); + flash->LoadMovie(0, _bstr_t(name).copy()); + } + Sleep(100); + flash->Play(); + + // change flash frame according user's status + int status; + if (fai->hFA.hContact) + status = DBGetContactSettingWord(fai->hFA.hContact, fai->getProto(), "Status", ID_STATUS_OFFLINE); + else + status = CallProtoService(fai->getProto(), PS_GETSTATUS, 0, 0); + + getFace(); + flash->SetVariable(L"face.emotion", _bstr_t(face).copy()); + flash->Release(); +} + +static void ShowBalloon(TCHAR *title, TCHAR *msg, int icon) { + MIRANDASYSTRAYNOTIFY msn = {0}; + msn.cbSize = sizeof(MIRANDASYSTRAYNOTIFY); + msn.dwInfoFlags = icon | NIIF_INTERN_UNICODE; + msn.tszInfo = TranslateTS(msg); + msn.tszInfoTitle = TranslateTS(title); + msn.uTimeout = 5000; + + CLIST_INTERFACE* c = (CLIST_INTERFACE*)CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, (LPARAM)g_hInst); + if (c) + c->pfnCListTrayNotify(&msn); +} + +static void prepareFlash(char* pProto, const char* pUrl, FLASHAVATAR& fa, IShockwaveFlash* flash) { + debug("Preparing flash...\n"); + if(flash == NULL) { + // Flash component is not registered in the system + ShowBalloon(LPGENT("Flash.ocx not registered!"), LPGENT("You don't have installed ShockwaveFlash interface in your system."), NIIF_ERROR); + + DestroyWindow(fa.hWindow); + fa.hWindow = 0; + return; + } + + if(flash->FlashVersion() == 0x80000) { + // Flash Version 8 has a bug which causes random crashes :( + ShowBalloon(LPGENT("Bugged Flash detected!"), LPGENT("You have installed Flash 8.\r\nThis version of Flash contains a bug which can causes random crashes.\r\nIt is recommended to upgrade or downgrade your Flash library"), NIIF_WARNING); + } + + // attach flash object to window + debug("Attaching flash to its window...\n"); + MyAtlAxAttachControl(flash, fa.hWindow, 0); + + // store avatar info + debug("Storing avatar info...\n"); + fa.cProto = pProto; + fa.cUrl = mir_strdup(pUrl); + + // create flash record + flash_avatar_item *flash_item = new flash_avatar_item(fa.hContact, fa, flash); + { + Lock l(cs); + FlashList.insert(flash_item); + } + + // avatar contains parameter, load it from remote place + if(strchr(fa.cUrl, '?')) { + debug("Flash with parameters, loading...\n"); + flash->LoadMovie(0, fa.cUrl); + } + + // refresh avatar's parent window + // InvalidateRect(fa.hParentWindow, NULL, FALSE); + + // create thread to download/load flash avatar + debug("Creating avatar thread...\n"); + flash->AddRef(); + mir_forkthread(&loadFlash_Thread, (void*)flash_item); + //loadFlash(new FlashPair(make_pair(fa, flash))); +} + +static int destroyAvatar(WPARAM wParam, LPARAM) +{ + flash_avatar_item key(((FLASHAVATAR*)wParam)->hContact, *(FLASHAVATAR*)wParam, NULL); + + Lock l(cs); + + flash_avatar_item *item = FlashList.find(&key); + if (item) { + if (item->pFlash) + item->pFlash->Release(); + if (item->hFA.hWindow) + DestroyWindow(item->hFA.hWindow); + mir_free(item->hFA.cUrl); + FlashList.remove(item); + delete item; + } + return 0; +} + +static int makeAvatar(WPARAM wParam, LPARAM) +{ + debug("Searching for flash avatar...\n"); + FLASHAVATAR* hFA = (FLASHAVATAR*)wParam; + + PROTO_AVATAR_INFORMATION AI = {0}; + AI.cbSize = sizeof(AI); + AI.hContact = hFA->hContact; + AI.format = PA_FORMAT_UNKNOWN; + + flash_avatar_item key(hFA->hContact, *hFA, NULL); + + bool avatarOK = false; + if(hFA->hContact) { + avatarOK = (int)CallProtoService(key.getProto(), PS_GETAVATARINFO, 0, (LPARAM)&AI) == GAIR_SUCCESS; + } else { + avatarOK = (int)CallProtoService(key.getProto(), PS_GETMYAVATAR, (WPARAM)AI.filename, (LPARAM)255) == 0; + if(avatarOK) { + char* ext = strrchr(AI.filename, '.'); + if(ext && (_stricmp(ext, ".xml") == 0)) + AI.format = PA_FORMAT_XML; + } + } + + if(!avatarOK) return 0; + debug("Avatar found...\n"); + + char* url = NULL; + switch(AI.format) { + case PA_FORMAT_SWF: + url = AI.filename; + break; + case PA_FORMAT_XML: { + int src = _open(AI.filename, _O_BINARY | _O_RDONLY); + if(src != -1) { + char pBuf[2048]; + char* urlBuf; + _read(src, pBuf, sizeof(pBuf)); + _close(src); + + urlBuf = strstr(pBuf, ""); + if(urlBuf) + url = strtok(urlBuf + 5, "\r\n <"); + else + return 0; + } else { + return 0; + } + break; + } + default: + destroyAvatar(wParam, 0); + return 0; + } + + Lock l(cs); + flash_avatar_item *item = FlashList.find(&key); + if (item) { + debug("Flash already exists...\n"); + hFA->hWindow = item->hFA.hWindow; + ShowWindow(hFA->hWindow, SW_SHOW); + + if(_stricmp(item->hFA.cUrl, url) != 0) { + debug("Refreshing flash...\n"); + IShockwaveFlash* flash = item->pFlash; + mir_free(item->hFA.cUrl); + FlashList.remove(item); + delete item; + + prepareFlash(key.getProto(), url, *hFA, flash); + } + } else { + debug("Creating new flash...\n"); + RECT rc; + GetWindowRect(hFA->hParentWindow, &rc); + hFA->hWindow = CreateWindowEx(WS_EX_TOPMOST, _T("AtlAxWin"), _T(""), WS_VISIBLE | WS_CHILD, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hFA->hParentWindow, (HMENU) 0, g_hInst, NULL); + + IShockwaveFlash* flash = NULL; + debug("Creating flash instance...\n"); + CoCreateInstance(__uuidof(ShockwaveFlash),0,CLSCTX_ALL, __uuidof(IShockwaveFlash), (void **)&flash); + debug("Initialized.\n"); + + prepareFlash(key.getProto(), url, *hFA, flash); + } + return 0; +} + +static int resizeAvatar(WPARAM wParam, LPARAM lParam) +{ + FLASHAVATAR* hFA = (FLASHAVATAR*)wParam; + RECT rc = *((LPRECT)lParam); + flash_avatar_item key(hFA->hContact, *hFA, NULL); + + Lock l(cs); + flash_avatar_item *item = FlashList.find(&key); + if (item) + SetWindowPos(item->hFA.hWindow, HWND_TOP, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW); + + return 0; +} + +static int setPos(WPARAM wParam, LPARAM lParam) +{ + FLASHAVATAR* hFA = (FLASHAVATAR*)wParam; + RECT rc = *((LPRECT)lParam); + flash_avatar_item key(hFA->hContact, *hFA, NULL); + + Lock l(cs); + flash_avatar_item *item = FlashList.find(&key); + if (item) + SetWindowPos(item->hFA.hWindow, HWND_TOP, rc.left, rc.top, rc.right, rc.bottom, SWP_SHOWWINDOW); + + return 0; +} + +static int getInfo(WPARAM wParam, LPARAM) +{ + FLASHAVATAR* hFA = (FLASHAVATAR*)wParam; + flash_avatar_item key(hFA->hContact, *hFA, NULL); + + Lock l(cs); + flash_avatar_item *item = FlashList.find(&key); + if (item) { + //IShockwaveFlash* flash = item->pFlash; + hFA->hWindow = item->hFA.hWindow; + hFA->cUrl = item->hFA.cUrl; + hFA->cProto = item->hFA.cProto; + } + return 0; +} + +static int setEmoFace(WPARAM wParam, LPARAM lParam) +{ + FLASHAVATAR* hFA = (FLASHAVATAR*)wParam; + flash_avatar_item key(hFA->hContact, *hFA, NULL); + + Lock l(cs); + flash_avatar_item *item = FlashList.find(&key); + if (item && item->pFlash) { + IShockwaveFlash* flash = item->pFlash; + flash->SetVariable(L"face.emotion", (BSTR)lParam); + } + return 0; +} + +static int setBkColor(WPARAM wParam, LPARAM lParam) +{ + FLASHAVATAR* hFA = (FLASHAVATAR*)wParam; + COLORREF clr = (COLORREF)lParam; + flash_avatar_item key(hFA->hContact, *hFA, NULL); + + Lock l(cs); + flash_avatar_item *item = FlashList.find(&key); + if (item && item->pFlash) { + IShockwaveFlash* flash = item->pFlash; + + char buf[10]; + _snprintf(buf, sizeof(buf), "%02X%02X%02X", LOBYTE(LOWORD(clr)), HIBYTE(LOWORD(clr)), LOBYTE(HIWORD(clr))); + flash->put_BGColor(_bstr_t(buf)); + } + return 0; +} + +static int ownStatusChanged(WPARAM wParam, LPARAM lParam) +{ + WORD status = (WORD)wParam; + const char* proto = (char*)lParam; + + Lock l(cs); + for(int i = 0; i < FlashList.getCount(); i++) { + flash_avatar_item *item = FlashList[i]; + if(item->hContact == NULL && (!proto || (strcmpnull(item->hFA.cProto, proto) == 0))) { + IShockwaveFlash* flash = item->pFlash; + if (flash) { + getFace(); + flash->SetVariable(L"face.emotion", _bstr_t(face).copy()); + } + } else if (item->hContact) + break; // the list is sorted by hContact + } + return 0; +} + +static int statusChanged(WPARAM wParam, LPARAM lParam) +{ + WORD status = HIWORD(lParam); + + Lock l(cs); + for(int i = 0; i < FlashList.getCount(); i++) { + flash_avatar_item *item = FlashList[i]; + if (item->hContact == (HANDLE)wParam) { + IShockwaveFlash* flash = item->pFlash; + if (flash) { + getFace(); + flash->SetVariable(L"face.emotion", _bstr_t(face).copy()); + } + } else if (item->hContact > (HANDLE)wParam) + break; // the list is sorted by hContact + } + return 0; +} + +static int eventAdded(WPARAM wParam, LPARAM lParam) +{ + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)lParam , 0); + if (dbei.cbBlob == 0xFFFFFFFF) + return 0; + + dbei.pBlob = new BYTE[dbei.cbBlob]; + CallService(MS_DB_EVENT_GET, (WPARAM)lParam, (LPARAM) & dbei); + + if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_READ)) { + Lock l(cs); + if(FlashList.getCount() > 0) { + //size_t aLen = strlen((char *)dbei.pBlob)+1; + char* face = NULL; + + if( (strstr((char*)dbei.pBlob, (char*)":-)") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":)") != NULL) || + (strstr((char*)dbei.pBlob, (char*)";)") != NULL) || + (strstr((char*)dbei.pBlob, (char*)";-)") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"*THUMBS UP*") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"O:-)") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":P") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-P") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"*Drink*") != NULL)) { face = AV_SMILE; } + else + if( (strstr((char*)dbei.pBlob, (char*)":-(") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-$") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-!") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-X") != NULL)) { face = AV_SAD; } + else + if( (strstr((char*)dbei.pBlob, (char*)"*JOKINGLY*") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-D") != NULL)) { face = AV_LAUGH; } + else + if( (strstr((char*)dbei.pBlob, (char*)":'(") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":'-(") != NULL)) { face = AV_CRY; } + else + if( (strstr((char*)dbei.pBlob, (char*)">:o") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-@") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"*STOP*") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"]:->") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"@=") != NULL)) { face = AV_MAD; } + else + if( (strstr((char*)dbei.pBlob, (char*)":-*") != NULL) || + (strstr((char*)dbei.pBlob, (char*)":-[") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"*KISSED*") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"*KISSING*") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"@}->--") != NULL) || + (strstr((char*)dbei.pBlob, (char*)"*IN LOVE*") != NULL)) { face = AV_LOVE; } + else { + face = AV_NORMAL; + } + + HANDLE hContact = (dbei.flags & DBEF_SENT) ? 0 : (HANDLE)wParam; + for(int i=0; ihContact == hContact && !strcmpnull(dbei.szModule, item->getProto())) { + IShockwaveFlash* flash = item->pFlash; + flash->SetVariable(L"face.emotion", _bstr_t(face).copy()); + //break; + } else if (item->hContact > hContact) + break; // the list is sorted + } + } + } + + delete[] dbei.pBlob; + return 0; +} + + +static int systemModulesLoaded(WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + HMODULE hAtl = LoadLibrary(_T("atl")); + void* init = GetProcAddress(hAtl, "AtlAxWinInit"); _asm call init; + MyAtlAxAttachControl = (LPAtlAxAttachControl)GetProcAddress(hAtl, "AtlAxAttachControl"); + + hServices[0] = CreateServiceFunction(MS_FAVATAR_DESTROY, destroyAvatar); + hServices[1] = CreateServiceFunction(MS_FAVATAR_MAKE, makeAvatar); + hServices[2] = CreateServiceFunction(MS_FAVATAR_RESIZE, resizeAvatar); + hServices[3] = CreateServiceFunction(MS_FAVATAR_SETPOS, setPos); + hServices[4] = CreateServiceFunction(MS_FAVATAR_GETINFO, getInfo); + hServices[5] = CreateServiceFunction(MS_FAVATAR_SETEMOFACE, setEmoFace); + hServices[6] = CreateServiceFunction(MS_FAVATAR_SETBKCOLOR, setBkColor); + + hHooks[1] = HookEvent(ME_DB_EVENT_ADDED, eventAdded); + hHooks[2] = HookEvent("Miranda/StatusChange/ContactStatusChanged", statusChanged); // NewStatusNotify + hHooks[3] = HookEvent(ME_CLIST_STATUSMODECHANGE, ownStatusChanged); + + NETLIBUSER nl_user = {0}; + nl_user.cbSize = sizeof(nl_user); + nl_user.szSettingsModule = "FlashAvatars"; + nl_user.flags = NUF_OUTGOING | NUF_HTTPCONNS; + nl_user.szDescriptiveName = Translate("Flash Avatars"); + + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nl_user); + + TCHAR path[MAX_PATH]; + if (ServiceExists(MS_UTILS_REPLACEVARS)) + { // default Avatar Cache path for MIM 0.8+ + TCHAR *tmpPath = Utils_ReplaceVarsT(_T("%miranda_avatarcache%")); + mir_sntprintf(path, MAX_PATH, _T("%s\\%s\\"), tmpPath, _T("Flash")); + mir_free(tmpPath); + } // default for older Mirandas + else + CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)(_T("Flash\\")), (LPARAM)path); + hAvatarsFolder = FoldersRegisterCustomPathT("Flash Avatars", "Avatars Cache", path); + + return 0; +} + + +extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 4, 0, 0)) + return NULL; + + TCHAR filename[MAX_PATH]; + GetModuleFileName(g_hInst, filename, SIZEOF(filename)); + + DWORD unused; + DWORD verInfoSize = GetFileVersionInfoSize(filename, &unused); + PVOID pVerInfo = malloc(verInfoSize); + GetFileVersionInfo(filename, 0, verInfoSize, pVerInfo); + + TCHAR *productVersion; + UINT blockSize; + VerQueryValue(pVerInfo, _T("\\StringFileInfo\\040504b0\\FileVersion"), (PVOID*)&productVersion, &blockSize); + +#ifdef _UNICODE + _snprintf(pluginName, SIZEOF(pluginName), "Flash avatars service [build #%S]", _tcsrchr(productVersion, ' ') + 1); +#else + _snprintf(pluginName, SIZEOF(pluginName), "Flash avatars service [build #%s]", strrchr(productVersion, ' ') + 1); +#endif + pluginInfo.shortName = pluginName; + + free(pVerInfo); + return &pluginInfo; +} + +static const MUUID interfaces[] = { { 0xc6fbb128, 0x81b4, 0x4221, { 0xa4, 0xb9, 0xe6, 0x34, 0x7c, 0x26, 0x4a, 0x49 } }, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + mir_getMMI(&mmi); + mir_getLI(&li); + + hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, systemModulesLoaded); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + // Shutdown cleanup + { + Lock l(cs); + for (int i = FlashList.getCount()-1; i >= 0; i--) + { + flash_avatar_item *item = FlashList[i]; + if (item->pFlash) + item->pFlash->Release(); + if (item->hFA.hWindow) + DestroyWindow(item->hFA.hWindow); + mir_free(item->hFA.cUrl); + delete item; + } + FlashList.destroy(); + } + + int i; + + for (i = 0; i < SIZEOF(hHooks); i++) + if (hHooks[i]) + UnhookEvent(hHooks[i]); + + for (i = 0; i < SIZEOF(hServices); i++) + if (hServices[i]) + DestroyServiceFunction(hServices[i]); + + if (hNetlibUser) + CallService(MS_NETLIB_CLOSEHANDLE, (WPARAM)hNetlibUser, 0); + + return 0; +} + +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD /*dwReason*/, LPVOID /*reserved*/) +{ + g_hInst = hInstDLL; + return TRUE; +} diff --git a/FlashAvatars/changelog.txt b/FlashAvatars/changelog.txt new file mode 100644 index 0000000..79a9b5a --- /dev/null +++ b/FlashAvatars/changelog.txt @@ -0,0 +1,81 @@ +* 0.0.0.1 + initial version + +* 0.0.1.1 + changed service functions + avatars should work correctly + +* 0.0.1.2 + better switching when user changes flash avatar to another flash avatar + avatar faces on status change + support/service constants are now in separate file (m_flash.h) + shutdown cleanup + +* 0.0.1.3 + FLASHAVATAR structure is used to post more information in service functions + flash object is created for each flash avatar, it solves many problems + +* 0.0.1.4 + avatar faces on standard ICQ emoticon + invalidate parent object after creating flash object + changed services' names (for the last time!) + +* 0.0.1.5 + added support to have displayed more flash avatars for same contact at one time + added message when flash.ocx isn't registered + +* 0.0.1.6 + fixed a crash when xml file doesn't exist + used standard protocol service to get avatar path + made thread safe + +* 0.0.1.7 + default protocol is ICQ for contact with unknown protocol + added support for own flash avatars (requires small change in tabsrmm and icq plugins) + fixed creating more avatars for one contact + fixed crash with invalid xml file + support for flashavatar background color per contact (set in message window) + +* 0.0.1.8 + changed project settings to decrease library size + +* 0.0.1.9 + using STLPort + removed ATL dependency + fixed iterator corruption when deleting flash avatar + fixed avatar smileys + +* 0.0.1.10 + added tZers support + using hash_multimap + +* 0.0.1.11 + added bad flash version check + disabled tZers support + using multimap instead of hash_multimap again + MS_FAVATAR_RESIZE function supports changing flash position + hopefully fixed crash when flash.ocx is not registered + added MS_FAVATAR_SETBKCOLOR service to allow setting flash background color + +* 0.0.1.12 + fixed disappeared flash avatar when resizing + added MS_FAVATAR_SETPOS service to set avatar position + +* 0.0.1.13 + code cleanup + not displaying ICQ flash avatar for unknown protocol + definitely removed tZers support + added reserved memory space to FLASHAVATAR structure, so we could extend it in the future + added flash default width and height macros to m_flash.h + added own downloading routine, so it respects Miranda's NetLib settings + added flash avatar caching + flash avatar downloading/loading routine moved to own thread + fixed invalid XML parsing + KNOWN PROBLEM: some icq5 self-made flash avatars (from Devil factory) can't be loaded from cache and in thread, so it uses default way for them + fixed thread handle leak + strings are translatable + +* 0.0.1.14 + added support for folders plugin + really fixed the thread handle leak + some code cleanup \ No newline at end of file diff --git a/FlashAvatars/criticalsection.h b/FlashAvatars/criticalsection.h new file mode 100644 index 0000000..6524b49 --- /dev/null +++ b/FlashAvatars/criticalsection.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if !defined(CRITICAL_SECTION_H) +#define CRITICAL_SECTION_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CriticalSection +{ +public: + void enter() throw() { + EnterCriticalSection(&cs); + } + void leave() throw() { + LeaveCriticalSection(&cs); + } + CriticalSection() throw() { + InitializeCriticalSection(&cs); + } + ~CriticalSection() throw() { + DeleteCriticalSection(&cs); + } +private: + CRITICAL_SECTION cs; + + CriticalSection(const CriticalSection&); + CriticalSection& operator=(const CriticalSection&); +}; + +template +class LockBase { +public: + LockBase(T& aCs) throw() : cs(aCs) { cs.enter(); } + ~LockBase() throw() { cs.leave(); } +private: + LockBase& operator=(const LockBase&); + T& cs; +}; +typedef LockBase Lock; + +/* +template +class RWLock +{ +public: + RWLock() throw() : cs(), readers(0) { } + ~RWLock() throw() { } + + void enterRead() throw() { + cs.enter(); + InterlockedIncrement(&readers); + cs.leave(); + } + void leaveRead() throw() { + InterlockedDecrement(&readers); + } + void enterWrite() throw() { + cs.enter(); + while(readers > 0) { + ::Sleep(1); + } + } + void leaveWrite() { + cs.leave(); + } +private: + T cs; + volatile long readers; +}; + +template +class RLock { +public: + RLock(RWLock& aRwl) throw() : rwl(aRwl) { rwl.enterRead(); } + ~RLock() throw() { rwl.leaveRead(); } +private: + RLock& operator=(const RLock&); + RWLock& rwl; +}; + +template +class WLock { +public: + WLock(RWLock& aRwl) throw() : rwl(aRwl) { rwl.enterWrite(); } + ~WLock() throw() { rwl.leaveWrite(); } +private: + WLock& operator=(const WLock&); + RWLock& rwl; +}; +*/ +#endif // !defined(CRITICAL_SECTION_H) + +/** + * @file + * $Id: CriticalSection.h,v 1.20 2006/03/05 10:17:03 bigmuscle Exp $ + */ diff --git a/FlashAvatars/resource.h b/FlashAvatars/resource.h new file mode 100644 index 0000000..cbedd28 --- /dev/null +++ b/FlashAvatars/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by FlashAvatars.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/FlashAvatars/stdafx.cpp b/FlashAvatars/stdafx.cpp new file mode 100644 index 0000000..a70d872 --- /dev/null +++ b/FlashAvatars/stdafx.cpp @@ -0,0 +1,7 @@ +// stdafx.cpp : source file that includes just the standard includes +// cflash.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + diff --git a/FlashAvatars/stdafx.h b/FlashAvatars/stdafx.h new file mode 100644 index 0000000..73ee89a --- /dev/null +++ b/FlashAvatars/stdafx.h @@ -0,0 +1,57 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently + +#pragma once +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define BZ_NO_STDIO + +#ifdef _WIN32 +# define _WIN32_WINNT 0x0500 +# define _WIN32_IE 0x0501 +#endif + +#if defined(UNICODE) && !defined(_UNICODE) +# define _UNICODE +#endif + +#ifdef _DEBUG +# define _STLP_DEBUG 1 +#endif + +#define _STLP_DONT_USE_SHORT_STRING_OPTIM 1 // Uses small string buffer, so it saves memory for a lot of strings +#define _STLP_USE_PTR_SPECIALIZATIONS 1 // Reduces some code bloat +#define _STLP_USE_TEMPLATE_EXPRESSION 1 // Speeds up string concatenation +#define _STLP_NO_ANACHRONISMS 1 + +#include +#include + + +#ifdef _DEBUG + +inline void _cdecl debugTrace(const char* format, ...) +{ + va_list args; + va_start(args, format); + + char buf[512]; + + _vsnprintf(buf, sizeof(buf), format, args); + OutputDebugStringA(buf); + va_end(args); +} + +# define debug debugTrace +#define assert(exp) \ +do { if (!(exp)) { \ + debug("Assertion hit in %s(%d): " #exp "\n", __FILE__, __LINE__); \ + if(1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, #exp)) \ +_CrtDbgBreak(); } } while(false) + +#else +# define debug +# define assert +#endif + + -- cgit v1.2.3