summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj48
-rw-r--r--protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj.filters114
-rw-r--r--protocols/Gadu-Gadu/avatar.cpp (renamed from protocols/Gadu-Gadu/avatar.c)255
-rw-r--r--protocols/Gadu-Gadu/core.c1841
-rw-r--r--protocols/Gadu-Gadu/core.cpp1765
-rw-r--r--protocols/Gadu-Gadu/dialogs.c1042
-rw-r--r--protocols/Gadu-Gadu/dialogs.cpp1016
-rw-r--r--protocols/Gadu-Gadu/dynstuff.cpp (renamed from protocols/Gadu-Gadu/dynstuff.c)47
-rw-r--r--protocols/Gadu-Gadu/filetransfer.cpp (renamed from protocols/Gadu-Gadu/filetransfer.c)697
-rw-r--r--protocols/Gadu-Gadu/gg.cpp (renamed from protocols/Gadu-Gadu/gg.c)370
-rw-r--r--protocols/Gadu-Gadu/gg.h194
-rw-r--r--protocols/Gadu-Gadu/groupchat.cpp (renamed from protocols/Gadu-Gadu/groupchat.c)326
-rw-r--r--protocols/Gadu-Gadu/icolib.cpp (renamed from protocols/Gadu-Gadu/icolib.c)0
-rw-r--r--protocols/Gadu-Gadu/image.cpp (renamed from protocols/Gadu-Gadu/image.c)801
-rw-r--r--protocols/Gadu-Gadu/import.c670
-rw-r--r--protocols/Gadu-Gadu/import.cpp651
-rw-r--r--protocols/Gadu-Gadu/keepalive.cpp (renamed from protocols/Gadu-Gadu/keepalive.c)36
-rw-r--r--protocols/Gadu-Gadu/libgadu/libgadu.h4
-rw-r--r--protocols/Gadu-Gadu/libgadu/pthread.c2
-rw-r--r--protocols/Gadu-Gadu/links.cpp (renamed from protocols/Gadu-Gadu/links.c)18
-rw-r--r--protocols/Gadu-Gadu/oauth.cpp (renamed from protocols/Gadu-Gadu/oauth.c)170
-rw-r--r--protocols/Gadu-Gadu/ownerinfo.cpp (renamed from protocols/Gadu-Gadu/ownerinfo.c)40
-rw-r--r--protocols/Gadu-Gadu/popups.cpp (renamed from protocols/Gadu-Gadu/popups.c)44
-rw-r--r--protocols/Gadu-Gadu/services.c1021
-rw-r--r--protocols/Gadu-Gadu/services.cpp330
-rw-r--r--protocols/Gadu-Gadu/sessions.cpp (renamed from protocols/Gadu-Gadu/sessions.c)284
-rw-r--r--protocols/Gadu-Gadu/token.cpp (renamed from protocols/Gadu-Gadu/token.c)49
-rw-r--r--protocols/Gadu-Gadu/userutils.cpp (renamed from protocols/Gadu-Gadu/userutils.c)209
28 files changed, 5420 insertions, 6624 deletions
diff --git a/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj b/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj
index fbbf4ef0f1..e4cb1fcd92 100644
--- a/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj
+++ b/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj
@@ -25,21 +25,21 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>MultiByte</CharacterSet>
+ <CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -205,27 +205,28 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="avatar.c" />
- <ClCompile Include="core.c" />
- <ClCompile Include="dialogs.c" />
- <ClCompile Include="dynstuff.c" />
- <ClCompile Include="filetransfer.c" />
- <ClCompile Include="gg.c">
+ <ClCompile Include="avatar.cpp" />
+ <ClCompile Include="core.cpp" />
+ <ClCompile Include="dialogs.cpp" />
+ <ClCompile Include="dynstuff.cpp" />
+ <ClCompile Include="filetransfer.cpp" />
+ <ClCompile Include="gg.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
- <ClCompile Include="groupchat.c" />
- <ClCompile Include="icolib.c" />
- <ClCompile Include="image.c" />
- <ClCompile Include="import.c" />
- <ClCompile Include="keepalive.c" />
- <ClCompile Include="links.c" />
- <ClCompile Include="oauth.c" />
- <ClCompile Include="ownerinfo.c" />
- <ClCompile Include="popups.c" />
- <ClCompile Include="services.c" />
- <ClCompile Include="sessions.c" />
- <ClCompile Include="token.c" />
- <ClCompile Include="userutils.c" />
+ <ClCompile Include="gg_proto.cpp" />
+ <ClCompile Include="groupchat.cpp" />
+ <ClCompile Include="icolib.cpp" />
+ <ClCompile Include="image.cpp" />
+ <ClCompile Include="import.cpp" />
+ <ClCompile Include="keepalive.cpp" />
+ <ClCompile Include="links.cpp" />
+ <ClCompile Include="oauth.cpp" />
+ <ClCompile Include="ownerinfo.cpp" />
+ <ClCompile Include="popups.cpp" />
+ <ClCompile Include="services.cpp" />
+ <ClCompile Include="sessions.cpp" />
+ <ClCompile Include="token.cpp" />
+ <ClCompile Include="userutils.cpp" />
<ClCompile Include="libgadu\common.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -264,6 +265,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="gg_proto.h" />
<ClInclude Include="libgadu\compat.h" />
<ClInclude Include="libgadu\internal.h" />
<ClInclude Include="libgadu\libgadu.h" />
diff --git a/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj.filters b/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj.filters
index 762ede137b..0057590422 100644
--- a/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj.filters
+++ b/protocols/Gadu-Gadu/Gadu-Gadu_10.vcxproj.filters
@@ -18,98 +18,101 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="avatar.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\common.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="core.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\dcc.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="dialogs.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\dcc7.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="dynstuff.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\events.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="filetransfer.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\http.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="gg.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\libgadu.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="groupchat.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\pthread.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="icolib.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\pubdir.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="image.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\pubdir50.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="import.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\resolver.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="keepalive.c">
- <Filter>Source Files</Filter>
+ <ClCompile Include="libgadu\sha1.c">
+ <Filter>Source Files\libgadu</Filter>
</ClCompile>
- <ClCompile Include="links.c">
+ <ClCompile Include="libgadu\win32.c">
+ <Filter>Source Files\libgadu</Filter>
+ </ClCompile>
+ <ClCompile Include="avatar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="oauth.c">
+ <ClCompile Include="core.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="ownerinfo.c">
+ <ClCompile Include="dialogs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="popups.c">
+ <ClCompile Include="dynstuff.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="services.c">
+ <ClCompile Include="filetransfer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="sessions.c">
+ <ClCompile Include="gg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="token.c">
+ <ClCompile Include="groupchat.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="userutils.c">
+ <ClCompile Include="icolib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\common.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="image.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\dcc.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="import.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\dcc7.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="keepalive.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\events.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="links.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\http.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="oauth.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\libgadu.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="ownerinfo.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\pthread.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="popups.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\pubdir.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="services.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\pubdir50.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="sessions.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\resolver.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="token.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\sha1.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="userutils.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="libgadu\win32.c">
- <Filter>Source Files\libgadu</Filter>
+ <ClCompile Include="gg_proto.cpp">
+ <Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@@ -146,6 +149,9 @@
<ClInclude Include="version.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="gg_proto.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="icons\block.ico">
diff --git a/protocols/Gadu-Gadu/avatar.c b/protocols/Gadu-Gadu/avatar.cpp
index 39e49c12bf..74c90748cc 100644
--- a/protocols/Gadu-Gadu/avatar.c
+++ b/protocols/Gadu-Gadu/avatar.cpp
@@ -25,43 +25,41 @@
//////////////////////////////////////////////////////////
// Avatars support
-void gg_getavatarfilename(GGPROTO *gg, HANDLE hContact, char *pszDest, int cbLen)
+void GGPROTO::getAvatarFilename(HANDLE hContact, TCHAR *pszDest, int cbLen)
{
int tPathLen;
- char *path = (char *)alloca(cbLen);
- char *avatartype = NULL;
+ TCHAR *path = (TCHAR*)alloca(cbLen * sizeof(TCHAR));
+ TCHAR *avatartype = NULL;
- if (gg->hAvatarsFolder == NULL || FoldersGetCustomPath(gg->hAvatarsFolder, path, cbLen, "")) {
- char *tmpPath = Utils_ReplaceVars("%miranda_avatarcache%");
- tPathLen = mir_snprintf(pszDest, cbLen, "%s\\%s", tmpPath, GG_PROTO);
- mir_free(tmpPath);
+ if (hAvatarsFolder == NULL || FoldersGetCustomPathT(hAvatarsFolder, path, cbLen, _T(""))) {
+ mir_ptr<TCHAR> tmpPath( Utils_ReplaceVarsT( _T("%miranda_avatarcache%")));
+ tPathLen = mir_sntprintf(pszDest, cbLen, _T("%s\\%s"), (TCHAR*)tmpPath, m_tszUserName);
}
else {
- strcpy(pszDest, path);
- tPathLen = (int)strlen(pszDest);
+ _tcscpy(pszDest, path);
+ tPathLen = (int)_tcslen(pszDest);
}
- if (_access(pszDest, 0))
+ if (_taccess(pszDest, 0))
CallService(MS_UTILS_CREATEDIRTREE, 0, (LPARAM)pszDest);
- switch (DBGetContactSettingByte(hContact, GG_PROTO, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE)) {
- case PA_FORMAT_JPEG: avatartype = "jpg"; break;
- case PA_FORMAT_GIF: avatartype = "gif"; break;
- case PA_FORMAT_PNG: avatartype = "png"; break;
+ switch (db_get_b(hContact, m_szModuleName, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE)) {
+ case PA_FORMAT_JPEG: avatartype = _T("jpg"); break;
+ case PA_FORMAT_GIF: avatartype = _T("gif"); break;
+ case PA_FORMAT_PNG: avatartype = _T("png"); break;
}
if (hContact != NULL) {
DBVARIANT dbv;
- if (!DBGetContactSettingString(hContact, GG_PROTO, GG_KEY_AVATARHASH, &dbv)) {
- mir_snprintf(pszDest + tPathLen, cbLen - tPathLen, "\\%s.%s", dbv.pszVal, avatartype);
+ if (!db_get_s(hContact, m_szModuleName, GG_KEY_AVATARHASH, &dbv, DBVT_ASCIIZ)) {
+ mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s.%s"), dbv.pszVal, avatartype);
DBFreeVariant(&dbv);
}
}
- else
- mir_snprintf(pszDest + tPathLen, cbLen - tPathLen, "\\%s avatar.%s", GG_PROTO, avatartype);
+ else mir_sntprintf(pszDest + tPathLen, cbLen - tPathLen, _T("\\%s avatar.%s"), m_szModuleName, avatartype);
}
-void gg_getavatarfileinfo(GGPROTO *gg, uin_t uin, char **avatarurl, int *type)
+void GGPROTO::getAvatarFileInfo(uin_t uin, char **avatarurl, int *type)
{
NETLIBHTTPREQUEST req = {0};
NETLIBHTTPREQUEST *resp;
@@ -74,35 +72,35 @@ void gg_getavatarfileinfo(GGPROTO *gg, uin_t uin, char **avatarurl, int *type)
req.szUrl = szUrl;
mir_snprintf(szUrl, 128, "http://api.gadu-gadu.pl/avatars/%d/0.xml", uin);
req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_REDIRECT;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) {
if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
HXML hXml;
TCHAR *xmlAction;
TCHAR *tag;
- xmlAction = gg_a2t(resp->pData);
- tag = gg_a2t("result");
+ xmlAction = mir_a2t(resp->pData);
+ tag = mir_a2t("result");
hXml = xi.parseString(xmlAction, 0, tag);
if (hXml != NULL) {
HXML node;
char *blank;
- mir_free(tag); tag = gg_a2t("users/user/avatars/avatar");
+ mir_free(tag); tag = mir_a2t("users/user/avatars/avatar");
node = xi.getChildByPath(hXml, tag, 0);
- mir_free(tag); tag = gg_a2t("blank");
- blank = node != NULL ? gg_t2a(xi.getAttrValue(node, tag)) : NULL;
+ mir_free(tag); tag = mir_a2t("blank");
+ blank = (node != NULL) ? mir_t2a(xi.getAttrValue(node, tag)) : NULL;
if (blank != NULL && strcmp(blank, "1")) {
- mir_free(tag); tag = gg_a2t("users/user/avatars/avatar/bigAvatar");
+ mir_free(tag); tag = mir_a2t("users/user/avatars/avatar/bigAvatar");
node = xi.getChildByPath(hXml, tag, 0);
- *avatarurl = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
+ *avatarurl = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
- mir_free(tag); tag = gg_a2t("users/user/avatars/avatar/originBigAvatar");
+ mir_free(tag); tag = mir_a2t("users/user/avatars/avatar/originBigAvatar");
node = xi.getChildByPath(hXml, tag, 0);
if (node != NULL) {
- char *orgavurl = gg_t2a(xi.getText(node));
+ char *orgavurl = mir_t2a(xi.getText(node));
char *avtype = strrchr(orgavurl, '.');
avtype++;
if (!_stricmp(avtype, "jpg"))
@@ -121,10 +119,10 @@ void gg_getavatarfileinfo(GGPROTO *gg, uin_t uin, char **avatarurl, int *type)
mir_free(tag);
mir_free(xmlAction);
}
- else gg_netlog(gg, "gg_getavatarfileinfo(): Invalid response code from HTTP request");
+ else netlog("gg_getavatarfileinfo(): Invalid response code from HTTP request");
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
}
- else gg_netlog(gg, "gg_getavatarfileinfo(): No response from HTTP request");
+ else netlog("gg_getavatarfileinfo(): No response from HTTP request");
}
char *gg_avatarhash(char *param)
@@ -136,7 +134,7 @@ char *gg_avatarhash(char *param)
if (param == NULL || (result = (char *)mir_alloc(MIR_SHA1_HASH_SIZE * 2 + 1)) == NULL)
return NULL;
- mir_sha1_hash(param, (int)strlen(param), digest);
+ mir_sha1_hash((BYTE*)param, (int)strlen(param), digest);
for (i = 0; i < MIR_SHA1_HASH_SIZE; i++)
sprintf(result + (i<<1), "%02x", digest[i]);
@@ -149,15 +147,15 @@ typedef struct
char *AvatarURL;
} GGGETAVATARDATA;
-void gg_getavatar(GGPROTO *gg, HANDLE hContact, char *szAvatarURL)
+void GGPROTO::getAvatar(HANDLE hContact, char *szAvatarURL)
{
- if (gg->pth_avatar.dwThreadId) {
- GGGETAVATARDATA *data = mir_alloc(sizeof(GGGETAVATARDATA));
+ if (pth_avatar.dwThreadId) {
+ GGGETAVATARDATA *data = (GGGETAVATARDATA*)mir_alloc(sizeof(GGGETAVATARDATA));
data->hContact = hContact;
data->AvatarURL = mir_strdup(szAvatarURL);
- EnterCriticalSection(&gg->avatar_mutex);
- list_add(&gg->avatar_transfers, data, 0);
- LeaveCriticalSection(&gg->avatar_mutex);
+ EnterCriticalSection(&avatar_mutex);
+ list_add(&avatar_transfers, data, 0);
+ LeaveCriticalSection(&avatar_mutex);
}
}
@@ -167,59 +165,59 @@ typedef struct
int iWaitFor;
} GGREQUESTAVATARDATA;
-void gg_requestavatar(GGPROTO *gg, HANDLE hContact, int iWaitFor)
+void GGPROTO::requestAvatar(HANDLE hContact, int iWaitFor)
{
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)
- && gg->pth_avatar.dwThreadId) {
- GGREQUESTAVATARDATA *data = mir_alloc(sizeof(GGREQUESTAVATARDATA));
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)
+ && pth_avatar.dwThreadId) {
+ GGREQUESTAVATARDATA *data = (GGREQUESTAVATARDATA*)mir_alloc(sizeof(GGREQUESTAVATARDATA));
data->hContact = hContact;
data->iWaitFor = iWaitFor;
- EnterCriticalSection(&gg->avatar_mutex);
- list_add(&gg->avatar_requests, data, 0);
- LeaveCriticalSection(&gg->avatar_mutex);
+ EnterCriticalSection(&avatar_mutex);
+ list_add(&avatar_requests, data, 0);
+ LeaveCriticalSection(&avatar_mutex);
}
}
-void __cdecl gg_avatarrequestthread(GGPROTO *gg, void *empty)
+void __cdecl GGPROTO::avatarrequestthread(void*)
{
list_t l;
- gg_netlog(gg, "gg_avatarrequestthread(): Avatar Request Thread Starting");
- while (gg->pth_avatar.dwThreadId)
+ netlog("gg_avatarrequestthread(): Avatar Request Thread Starting");
+ while (pth_avatar.dwThreadId)
{
- EnterCriticalSection(&gg->avatar_mutex);
- if (gg->avatar_requests) {
- GGREQUESTAVATARDATA *data = (GGREQUESTAVATARDATA *)gg->avatar_requests->data;
+ EnterCriticalSection(&avatar_mutex);
+ if (avatar_requests) {
+ GGREQUESTAVATARDATA *data = (GGREQUESTAVATARDATA *)avatar_requests->data;
char *AvatarURL;
int AvatarType, iWaitFor = data->iWaitFor;
HANDLE hContact = data->hContact;
- list_remove(&gg->avatar_requests, data, 0);
+ list_remove(&avatar_requests, data, 0);
mir_free(data);
- LeaveCriticalSection(&gg->avatar_mutex);
+ LeaveCriticalSection(&avatar_mutex);
- gg_getavatarfileinfo(gg, DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0), &AvatarURL, &AvatarType);
+ getAvatarFileInfo( db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0), &AvatarURL, &AvatarType);
if (AvatarURL != NULL && strlen(AvatarURL) > 0)
- DBWriteContactSettingString(hContact, GG_PROTO, GG_KEY_AVATARURL, AvatarURL);
+ db_set_s(hContact, m_szModuleName, GG_KEY_AVATARURL, AvatarURL);
else
- DBDeleteContactSetting(hContact, GG_PROTO, GG_KEY_AVATARURL);
- DBWriteContactSettingByte(hContact, GG_PROTO, GG_KEY_AVATARTYPE, (BYTE)AvatarType);
- DBWriteContactSettingByte(hContact, GG_PROTO, GG_KEY_AVATARREQUESTED, 1);
+ db_unset(hContact, m_szModuleName, GG_KEY_AVATARURL);
+ db_set_b(hContact, m_szModuleName, GG_KEY_AVATARTYPE, (BYTE)AvatarType);
+ db_set_b(hContact, m_szModuleName, GG_KEY_AVATARREQUESTED, 1);
if (iWaitFor) {
PROTO_AVATAR_INFORMATIONT pai = {0};
pai.cbSize = sizeof(pai);
pai.hContact = hContact;
- if (gg_getavatarinfo(gg, (WPARAM)GAIF_FORCE, (LPARAM)&pai) != GAIR_WAITFOR)
- ProtoBroadcastAck(GG_PROTO, hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0);
+ if (getavatarinfo((WPARAM)GAIF_FORCE, (LPARAM)&pai) != GAIR_WAITFOR)
+ ProtoBroadcastAck(m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0);
}
- else ProtoBroadcastAck(GG_PROTO, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, 0, 0);
+ else ProtoBroadcastAck(m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, 0, 0);
}
- else LeaveCriticalSection(&gg->avatar_mutex);
+ else LeaveCriticalSection(&avatar_mutex);
- EnterCriticalSection(&gg->avatar_mutex);
- if (gg->avatar_transfers) {
- GGGETAVATARDATA *data = (GGGETAVATARDATA *)gg->avatar_transfers->data;
+ EnterCriticalSection(&avatar_mutex);
+ if (avatar_transfers) {
+ GGGETAVATARDATA *data = (GGGETAVATARDATA *)avatar_transfers->data;
NETLIBHTTPREQUEST req = {0};
NETLIBHTTPREQUEST *resp;
PROTO_AVATAR_INFORMATIONT pai = {0};
@@ -227,122 +225,121 @@ void __cdecl gg_avatarrequestthread(GGPROTO *gg, void *empty)
pai.cbSize = sizeof(pai);
pai.hContact = data->hContact;
- pai.format = DBGetContactSettingByte(pai.hContact, GG_PROTO, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE);
+ pai.format = db_get_b(pai.hContact, m_szModuleName, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE);
req.cbSize = sizeof(req);
req.requestType = REQUEST_GET;
req.szUrl = data->AvatarURL;
req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_REDIRECT;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) {
if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
int file_fd;
- gg_getavatarfilename(gg, pai.hContact, pai.filename, sizeof(pai.filename));
- file_fd = _open(pai.filename, _O_WRONLY | _O_TRUNC | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE);
+ getAvatarFilename(pai.hContact, pai.filename, sizeof(pai.filename));
+ file_fd = _topen(pai.filename, _O_WRONLY | _O_TRUNC | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE);
if (file_fd != -1) {
_write(file_fd, resp->pData, resp->dataLength);
_close(file_fd);
result = 1;
}
}
- else gg_netlog(gg, "gg_avatarrequestthread(): Invalid response code from HTTP request");
+ else netlog("gg_avatarrequestthread(): Invalid response code from HTTP request");
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
}
- else gg_netlog(gg, "gg_avatarrequestthread(): No response from HTTP request");
+ else netlog("gg_avatarrequestthread(): No response from HTTP request");
- ProtoBroadcastAck(GG_PROTO, pai.hContact, ACKTYPE_AVATAR,
+ ProtoBroadcastAck(m_szModuleName, pai.hContact, ACKTYPE_AVATAR,
result ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)&pai, 0);
if (!pai.hContact)
- CallService(MS_AV_REPORTMYAVATARCHANGED, (WPARAM)GG_PROTO, 0);
+ CallService(MS_AV_REPORTMYAVATARCHANGED, (WPARAM)m_szModuleName, 0);
- list_remove(&gg->avatar_transfers, data, 0);
+ list_remove(&avatar_transfers, data, 0);
mir_free(data->AvatarURL);
mir_free(data);
}
- LeaveCriticalSection(&gg->avatar_mutex);
+ LeaveCriticalSection(&avatar_mutex);
SleepEx(100, FALSE);
}
- for (l = gg->avatar_requests; l; l = l->next) {
+ for (l = avatar_requests; l; l = l->next) {
GGREQUESTAVATARDATA *data = (GGREQUESTAVATARDATA *)l->data;
mir_free(data);
}
- for (l = gg->avatar_transfers; l; l = l->next) {
+ for (l = avatar_transfers; l; l = l->next) {
GGGETAVATARDATA *data = (GGGETAVATARDATA *)l->data;
mir_free(data->AvatarURL);
mir_free(data);
}
- list_destroy(gg->avatar_requests, 0);
- list_destroy(gg->avatar_transfers, 0);
- gg_netlog(gg, "gg_avatarrequestthread(): Avatar Request Thread Ending");
+ list_destroy(avatar_requests, 0);
+ list_destroy(avatar_transfers, 0);
+ netlog("gg_avatarrequestthread(): Avatar Request Thread Ending");
}
-void gg_initavatarrequestthread(GGPROTO *gg)
+void GGPROTO::initavatarrequestthread()
{
DWORD exitCode = 0;
- GetExitCodeThread(gg->pth_avatar.hThread, &exitCode);
+ GetExitCodeThread(pth_avatar.hThread, &exitCode);
if (exitCode != STILL_ACTIVE) {
- gg->avatar_requests = gg->avatar_transfers = NULL;
- gg->pth_avatar.hThread = gg_forkthreadex(gg, gg_avatarrequestthread, NULL, &gg->pth_avatar.dwThreadId);
+ avatar_requests = avatar_transfers = NULL;
+ pth_avatar.hThread = forkthreadex(&GGPROTO::avatarrequestthread, NULL, &pth_avatar.dwThreadId);
}
}
-void gg_uninitavatarrequestthread(GGPROTO *gg)
+void GGPROTO::uninitavatarrequestthread()
{
- gg->pth_avatar.dwThreadId = 0;
+ pth_avatar.dwThreadId = 0;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_uninitavatarrequestthread(): Waiting until Avatar Request Thread finished, if needed.");
+ netlog("gg_uninitavatarrequestthread(): Waiting until Avatar Request Thread finished, if needed.");
#endif
- gg_threadwait(gg, &gg->pth_avatar);
+ threadwait(&pth_avatar);
}
-void __cdecl gg_getuseravatarthread(GGPROTO *gg, void *empty)
+void __cdecl GGPROTO::getuseravatarthread(void*)
{
PROTO_AVATAR_INFORMATIONT pai = {0};
char *AvatarURL;
int AvatarType;
- gg_getavatarfileinfo(gg, DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0), &AvatarURL, &AvatarType);
+ getAvatarFileInfo( db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0), &AvatarURL, &AvatarType);
if (AvatarURL != NULL && strlen(AvatarURL) > 0)
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_AVATARURL, AvatarURL);
+ db_set_s(NULL, m_szModuleName, GG_KEY_AVATARURL, AvatarURL);
else
- DBDeleteContactSetting(NULL, GG_PROTO, GG_KEY_AVATARURL);
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_AVATARTYPE, (BYTE)AvatarType);
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_AVATARREQUESTED, 1);
+ db_unset(NULL, m_szModuleName, GG_KEY_AVATARURL);
+ db_set_b(NULL, m_szModuleName, GG_KEY_AVATARTYPE, (BYTE)AvatarType);
+ db_set_b(NULL, m_szModuleName, GG_KEY_AVATARREQUESTED, 1);
pai.cbSize = sizeof(pai);
- gg_getavatarinfo(gg, (WPARAM)GAIF_FORCE, (LPARAM)&pai);
+ getavatarinfo((WPARAM)GAIF_FORCE, (LPARAM)&pai);
}
-void gg_getuseravatar(GGPROTO *gg)
+void GGPROTO::getUserAvatar()
{
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)
- && DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
- gg_forkthread(gg, gg_getuseravatarthread, NULL);
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)
+ && db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0))
+ forkthread(&GGPROTO::getuseravatarthread, NULL);
}
-void __cdecl gg_setavatarthread(GGPROTO *gg, void *param)
+void __cdecl GGPROTO::setavatarthread(void *param)
{
NETLIBHTTPHEADER httpHeaders[4];
NETLIBHTTPREQUEST req = {0};
NETLIBHTTPREQUEST *resp;
- char *szFilename = (char *)param;
+ TCHAR *szFilename = (TCHAR*)param;
const char *contentend = "\r\n--AaB03x--\r\n";
- char szUrl[128], uin[32], *authHeader, *data, *avatardata, content[256],
- *fileext, image_ext[4], image_type[11];
+ char szUrl[128], uin[32], *authHeader, *data, *avatardata, content[256], image_ext[4], image_type[11];
int file_fd, avatardatalen, datalen, contentlen, contentendlen, res = 0, repeat = 0;
- gg_netlog(gg, "gg_setavatar(): Trying to set user avatar using %s...", szFilename);
- UIN2ID(DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0), uin);
+ netlog("gg_setavatar(): Trying to set user avatar using %s...", szFilename);
+ UIN2ID(db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0), uin);
- file_fd = _open(szFilename, _O_RDONLY | _O_BINARY, _S_IREAD);
+ file_fd = _topen(szFilename, _O_RDONLY | _O_BINARY, _S_IREAD);
if (file_fd == -1) {
- gg_netlog(gg, "gg_setavatar(): Failed to open avatar file (%s).", strerror(errno));
+ netlog("gg_setavatar(): Failed to open avatar file (%s).", strerror(errno));
mir_free(szFilename);
- gg_getuseravatar(gg);
+ getUserAvatar();
return;
}
avatardatalen = _filelength(file_fd);
@@ -351,17 +348,17 @@ void __cdecl gg_setavatarthread(GGPROTO *gg, void *param)
_read(file_fd, avatardata, avatardatalen);
_close(file_fd);
- fileext = strrchr(szFilename, '.');
+ TCHAR *fileext = _tcsrchr(szFilename, '.');
fileext++;
- if (!_stricmp(fileext, "jpg")) {
+ if (!_tcsicmp(fileext, _T("jpg"))) {
strcpy(image_ext, "jpg");
strcpy(image_type, "image/jpeg");
}
- else if (!_stricmp(fileext, "gif")) {
+ else if (!_tcsicmp(fileext, _T("gif"))) {
strcpy(image_ext, "gif");
strcpy(image_type, "image/gif");
}
- else /*if (!_stricmp(fileext, "png"))*/ {
+ else {
strcpy(image_ext, "png");
strcpy(image_type, "image/png");
}
@@ -378,8 +375,8 @@ void __cdecl gg_setavatarthread(GGPROTO *gg, void *param)
memcpy(data + contentlen + avatardatalen, contentend, contentendlen);
mir_snprintf(szUrl, 128, "http://api.gadu-gadu.pl/avatars/%s/0.xml", uin);
- gg_oauth_checktoken(gg, 0);
- authHeader = gg_oauth_header(gg, "PUT", szUrl);
+ oauth_checktoken(0);
+ authHeader = oauth_header("PUT", szUrl);
req.cbSize = sizeof(req);
req.requestType = REQUEST_POST;
@@ -398,25 +395,25 @@ void __cdecl gg_setavatarthread(GGPROTO *gg, void *param)
req.pData = data;
req.dataLength = datalen;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) {
if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
#ifdef DEBUGMODE
- gg_netlog(gg, "%s", resp->pData);
+ netlog("%s", resp->pData);
#endif
res = 1;
}
- else gg_netlog(gg, "gg_setavatar(): Invalid response code from HTTP request");
+ else netlog("gg_setavatar(): Invalid response code from HTTP request");
if (resp->resultCode == 403 || resp->resultCode == 401)
repeat = 1;
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
}
- else gg_netlog(gg, "gg_setavatar(): No response from HTTP request");
+ else netlog("gg_setavatar(): No response from HTTP request");
if (repeat) { // Access Token expired - we need to obtain new
mir_free(authHeader);
- gg_oauth_checktoken(gg, 1);
- authHeader = gg_oauth_header(gg, "PUT", szUrl);
+ oauth_checktoken(1);
+ authHeader = oauth_header("PUT", szUrl);
ZeroMemory(&req, sizeof(req));
req.cbSize = sizeof(req);
@@ -428,18 +425,18 @@ void __cdecl gg_setavatarthread(GGPROTO *gg, void *param)
req.pData = data;
req.dataLength = datalen;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) {
if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
#ifdef DEBUGMODE
- gg_netlog(gg, "%s", resp->pData);
+ netlog("%s", resp->pData);
#endif
res = 1;
}
- else gg_netlog(gg, "gg_setavatar(): Invalid response code from HTTP request");
+ else netlog("gg_setavatar(): Invalid response code from HTTP request");
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
}
- else gg_netlog(gg, "gg_setavatar(): No response from HTTP request");
+ else netlog("gg_setavatar(): No response from HTTP request");
}
mir_free(authHeader);
@@ -447,15 +444,15 @@ void __cdecl gg_setavatarthread(GGPROTO *gg, void *param)
mir_free(data);
if (res)
- gg_netlog(gg, "gg_setavatar(): User avatar set successfully.");
+ netlog("gg_setavatar(): User avatar set successfully.");
else
- gg_netlog(gg, "gg_setavatar(): Failed to set user avatar.");
+ netlog("gg_setavatar(): Failed to set user avatar.");
mir_free(szFilename);
- gg_getuseravatar(gg);
+ getUserAvatar();
}
-void gg_setavatar(GGPROTO *gg, const char *szFilename)
+void GGPROTO::setAvatar(const TCHAR *szFilename)
{
- gg_forkthread(gg, gg_setavatarthread, (void*)mir_strdup(szFilename));
+ forkthread(&GGPROTO::setavatarthread, mir_tstrdup(szFilename));
}
diff --git a/protocols/Gadu-Gadu/core.c b/protocols/Gadu-Gadu/core.c
deleted file mode 100644
index 0641f7df25..0000000000
--- a/protocols/Gadu-Gadu/core.c
+++ /dev/null
@@ -1,1841 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Gadu-Gadu Plugin for Miranda IM
-//
-// Copyright (c) 2003-2009 Adam Strzelecki <ono+miranda@java.pl>
-// Copyright (c) 2009-2012 Bartosz Bia³ek
-//
-// 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 "gg.h"
-#include <errno.h>
-#include <io.h>
-
-////////////////////////////////////////////////////////////
-// Swap bits in DWORD
-uint32_t swap32(uint32_t x)
-{
- return (uint32_t)
- (((x & (uint32_t) 0x000000ffU) << 24) |
- ((x & (uint32_t) 0x0000ff00U) << 8) |
- ((x & (uint32_t) 0x00ff0000U) >> 8) |
- ((x & (uint32_t) 0xff000000U) >> 24));
-}
-
-////////////////////////////////////////////////////////////
-// Is online function
-GGINLINE int gg_isonline(GGPROTO *gg)
-{
- int isonline;
- EnterCriticalSection(&gg->sess_mutex);
- isonline = (gg->sess != NULL);
- LeaveCriticalSection(&gg->sess_mutex);
-
- return isonline;
-}
-
-////////////////////////////////////////////////////////////
-// Send disconnect request and wait for server thread to die
-void gg_disconnect(GGPROTO *gg)
-{
- // If main loop then send disconnect request
- if (gg_isonline(gg))
- {
- // Fetch proper status msg
- char *szMsg = NULL;
-
- // Loadup status
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_LEAVESTATUSMSG, GG_KEYDEF_LEAVESTATUSMSG))
- {
- DBVARIANT dbv;
- switch (DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, GG_KEYDEF_LEAVESTATUS))
- {
- case ID_STATUS_ONLINE:
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg->modemsg.online);
- LeaveCriticalSection(&gg->modemsg_mutex);
- if (!szMsg &&
- !DBGetContactSettingString(NULL, "SRAway", gg_status2db(ID_STATUS_ONLINE, "Default"), &dbv))
- {
- if (dbv.pszVal && *(dbv.pszVal))
- szMsg = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- break;
- case ID_STATUS_AWAY:
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg->modemsg.away);
- LeaveCriticalSection(&gg->modemsg_mutex);
- if (!szMsg &&
- !DBGetContactSettingString(NULL, "SRAway", gg_status2db(ID_STATUS_AWAY, "Default"), &dbv))
- {
- if (dbv.pszVal && *(dbv.pszVal))
- szMsg = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- break;
- case ID_STATUS_DND:
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg->modemsg.dnd);
- LeaveCriticalSection(&gg->modemsg_mutex);
- if (!szMsg &&
- !DBGetContactSettingString(NULL, "SRAway", gg_status2db(ID_STATUS_DND, "Default"), &dbv))
- {
- if (dbv.pszVal && *(dbv.pszVal))
- szMsg = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- break;
- case ID_STATUS_FREECHAT:
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg->modemsg.freechat);
- LeaveCriticalSection(&gg->modemsg_mutex);
- if (!szMsg &&
- !DBGetContactSettingString(NULL, "SRAway", gg_status2db(ID_STATUS_FREECHAT, "Default"), &dbv))
- {
- if (dbv.pszVal && *(dbv.pszVal))
- szMsg = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- break;
- case ID_STATUS_INVISIBLE:
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg->modemsg.invisible);
- LeaveCriticalSection(&gg->modemsg_mutex);
- if (!szMsg &&
- !DBGetContactSettingString(NULL, "SRAway", gg_status2db(ID_STATUS_INVISIBLE, "Default"), &dbv))
- {
- if (dbv.pszVal && *(dbv.pszVal))
- szMsg = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- break;
- default:
- // Set last status
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg_getstatusmsg(gg, gg->proto.m_iStatus));
- LeaveCriticalSection(&gg->modemsg_mutex);
- }
- }
-
- EnterCriticalSection(&gg->sess_mutex);
- // Check if it has message
- if (szMsg)
- {
- gg_change_status_descr(gg->sess, GG_STATUS_NOT_AVAIL_DESCR, szMsg);
- mir_free(szMsg);
- // Wait for disconnection acknowledge
- }
- else
- {
- gg_change_status(gg->sess, GG_STATUS_NOT_AVAIL);
- // Send logoff immediately
- gg_logoff(gg->sess);
- }
- LeaveCriticalSection(&gg->sess_mutex);
- }
- // Else cancel connection attempt
- else if (gg->sock)
- closesocket(gg->sock);
-}
-
-////////////////////////////////////////////////////////////
-// DNS lookup function
-uint32_t gg_dnslookup(GGPROTO *gg, char *host)
-{
- uint32_t ip;
- struct hostent *he;
-
- ip = inet_addr(host);
- if(ip != INADDR_NONE)
- {
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dnslookup(): Parameter \"%s\" is already IP number.", host);
-#endif
- return ip;
- }
- he = gethostbyname(host);
- if(he)
- {
- ip = *(uint32_t *) he->h_addr_list[0];
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dnslookup(): Parameter \"%s\" was resolved to %d.%d.%d.%d.", host,
- LOBYTE(LOWORD(ip)), HIBYTE(LOWORD(ip)), LOBYTE(HIWORD(ip)), HIBYTE(HIWORD(ip)));
-#endif
- return ip;
- }
- gg_netlog(gg, "gg_dnslookup(): Cannot resolve hostname \"%s\".", host);
- return 0;
-}
-
-////////////////////////////////////////////////////////////
-// Host list decoder
-typedef struct
-{
- char hostname[128];
- int port;
-} GGHOST;
-#define ISHOSTALPHA(a) (((a) >= '0' && (a) <= '9') || ((a) >= 'a' && (a) <= 'z') || (a) == '.' || (a) == '-')
-int gg_decodehosts(char *var, GGHOST *hosts, int max)
-{
- int hp = 0;
- char *hostname = NULL;
- char *portname = NULL;
-
- while(var && *var && hp < max)
- {
- if(ISHOSTALPHA(*var))
- {
- hostname = var;
-
- while(var && *var && ISHOSTALPHA(*var)) var ++;
-
- if(var && *var == ':' && var++ && *var && isdigit(*var))
- {
- *(var - 1) = 0;
- portname = var;
- while(var && *var && isdigit(*var)) var++;
- if (*var) { *var = 0; var ++; }
- }
- else
- if (*var) { *var = 0; var ++; }
-
- // Insert new item
- hosts[hp].hostname[127] = 0;
- strncpy(hosts[hp].hostname, hostname, 127);
- hosts[hp].port = portname ? atoi(portname) : 443;
- hp ++;
-
- // Zero the names
- hostname = NULL;
- portname = NULL;
- }
- else
- var ++;
- }
- return hp;
-}
-
-////////////////////////////////////////////////////////////
-// Main connection session thread
-void __cdecl gg_mainthread(GGPROTO *gg, void *empty)
-{
- // Miranda variables
- NETLIBUSERSETTINGS nlus = {0};
- DBVARIANT dbv;
- // Gadu-Gadu variables
- struct gg_login_params p = {0};
- struct gg_event *e;
- struct gg_session *sess;
- // Host cycling variables
- int hostnum = 0, hostcount = 0;
- GGHOST hosts[64];
- // Gadu-gadu login errors
- static const struct tagReason { int type; char *str; } reason[] = {
- { GG_FAILURE_RESOLVING, "Miranda was unable to resolve the name of the Gadu-Gadu server to its numeric address." },
- { GG_FAILURE_CONNECTING, "Miranda was unable to make a connection with a server. It is likely that the server is down, in which case you should wait for a while and try again later." },
- { GG_FAILURE_INVALID, "Received invalid server response." },
- { GG_FAILURE_READING, "The connection with the server was abortively closed during the connection attempt. You may have lost your local network connection." },
- { GG_FAILURE_WRITING, "The connection with the server was abortively closed during the connection attempt. You may have lost your local network connection." },
- { GG_FAILURE_PASSWORD, "Your Gadu-Gadu number and password combination was rejected by the Gadu-Gadu server. Please check login details at M->Options->Network->Gadu-Gadu and try again." },
- { GG_FAILURE_404, "Connecting to Gadu-Gadu hub failed." },
- { GG_FAILURE_TLS, "Cannot establish secure connection." },
- { GG_FAILURE_NEED_EMAIL, "Server disconnected asking you for changing your e-mail." },
- { GG_FAILURE_INTRUDER, "Too many login attempts with invalid password." },
- { GG_FAILURE_UNAVAILABLE, "Gadu-Gadu servers are now down. Try again later." },
- { 0, "Unknown" }
- };
- time_t logonTime = 0;
- time_t timeDeviation = DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_TIMEDEVIATION, GG_KEYDEF_TIMEDEVIATION);
- int gg_failno = 0;
-
- gg_netlog(gg, "gg_mainthread(%x): Server Thread Starting", gg);
-#ifdef DEBUGMODE
- gg_debug_level = GG_DEBUG_NET | GG_DEBUG_TRAFFIC | GG_DEBUG_FUNCTION | GG_DEBUG_MISC;
-#else
- gg_debug_level = 0;
-#endif
-
- // Broadcast that service is connecting
- gg_broadcastnewstatus(gg, ID_STATUS_CONNECTING);
-
- // Client version and misc settings
- p.client_version = GG_DEFAULT_CLIENT_VERSION;
- p.protocol_version = GG_DEFAULT_PROTOCOL_VERSION;
- p.protocol_features = GG_FEATURE_DND_FFC | GG_FEATURE_UNKNOWN_100 | GG_FEATURE_USER_DATA | GG_FEATURE_MSG_ACK | GG_FEATURE_TYPING_NOTIFICATION | GG_FEATURE_MULTILOGON;
- p.encoding = GG_ENCODING_CP1250;
- p.status_flags = GG_STATUS_FLAG_UNKNOWN;
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWLINKS, GG_KEYDEF_SHOWLINKS))
- p.status_flags |= GG_STATUS_FLAG_SPAM;
-
- // Use audio
- /* p.has_audio = 1; */
-
- // Use async connections
- /* p.async = 1; */
-
- // Send Era Omnix info if set
- p.era_omnix = DBGetContactSettingByte(NULL, GG_PROTO, "EraOmnix", 0);
-
- // Setup proxy
- nlus.cbSize = sizeof(nlus);
- if(CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)gg->netlib, (LPARAM)&nlus))
- {
- if(nlus.useProxy)
- gg_netlog(gg, "gg_mainthread(%x): Using proxy %s:%d.", gg, nlus.szProxyServer, nlus.wProxyPort);
- gg_proxy_enabled = nlus.useProxy;
- gg_proxy_host = nlus.szProxyServer;
- gg_proxy_port = nlus.wProxyPort;
- if(nlus.useProxyAuth)
- {
- gg_proxy_username = nlus.szProxyAuthUser;
- gg_proxy_password = nlus.szProxyAuthPassword;
- }
- else
- gg_proxy_username = gg_proxy_password = NULL;
- }
- else
- {
- gg_netlog(gg, "gg_mainthread(%x): Failed loading proxy settings.", gg);
- gg_proxy_enabled = 0;
- }
-
- // Check out manual host setting
- if(DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_MANUALHOST, GG_KEYDEF_MANUALHOST))
- {
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_SERVERHOSTS, &dbv))
- {
- hostcount = gg_decodehosts(dbv.pszVal, hosts, 64);
- DBFreeVariant(&dbv);
- }
- }
-
- // Readup password
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv))
- {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- p.password = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- {
- gg_netlog(gg, "gg_mainthread(%x): No password specified. Exiting.", gg);
- gg_broadcastnewstatus(gg, ID_STATUS_OFFLINE);
- return;
- }
-
- // Readup number
- if (!(p.uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0)))
- {
- gg_netlog(gg, "gg_mainthread(%x): No Gadu-Gadu number specified. Exiting.", gg);
- gg_broadcastnewstatus(gg, ID_STATUS_OFFLINE);
- mir_free(p.password);
- return;
- }
-
- // Readup SSL/TLS setting
- if(p.tls = DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SSLCONN, GG_KEYDEF_SSLCONN))
- gg_netlog(gg, "gg_mainthread(%x): Using TLS/SSL for connections.", gg);
-
- // Gadu-Gadu accepts image sizes upto 255
- p.image_size = 255;
-
- ////////////////////////////// DCC STARTUP /////////////////////////////
- // Uin is ok so startup dcc if not started already
- if (!gg->dcc)
- {
- gg->event = CreateEvent(NULL, TRUE, FALSE, NULL);
- gg_dccstart(gg);
-
- // Wait for DCC
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_mainthread(%x): Waiting DCC service to start...", gg);
-#endif
- while (WaitForSingleObjectEx(gg->event, INFINITE, TRUE) != WAIT_OBJECT_0);
- CloseHandle(gg->event); gg->event = NULL;
- }
- // Check if dcc is running and setup forwarding port
- if(gg->dcc && DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_FORWARDING, GG_KEYDEF_FORWARDING))
- {
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_FORWARDHOST, &dbv))
- {
- if (!(p.external_addr = gg_dnslookup(gg, dbv.pszVal)))
- {
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("External direct connections hostname %s is invalid. Disabling external host forwarding."), dbv.pszVal);
- gg_showpopup(gg, GG_PROTONAME, error, GG_POPUP_WARNING | GG_POPUP_ALLOW_MSGBOX);
- }
- else
- gg_netlog(gg, "gg_mainthread(%x): Loading forwarding host %s and port %d.", dbv.pszVal, p.external_port, gg);
- if(p.external_addr) p.external_port = DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_FORWARDPORT, GG_KEYDEF_FORWARDPORT);
- DBFreeVariant(&dbv);
- }
- }
- // Setup client port
- if(gg->dcc) p.client_port = gg->dcc->port;
-
-retry:
- // Loadup startup status & description
- EnterCriticalSection(&gg->modemsg_mutex);
- p.status_descr = mir_strdup(gg_getstatusmsg(gg, gg->proto.m_iDesiredStatus));
- p.status = status_m2gg(gg, gg->proto.m_iDesiredStatus, p.status_descr != NULL);
-
- gg_netlog(gg, "gg_mainthread(%x): Connecting with number %d, status %d and description \"%s\".", gg, p.uin, gg->proto.m_iDesiredStatus,
- p.status_descr ? p.status_descr : "<none>");
- LeaveCriticalSection(&gg->modemsg_mutex);
-
- // Check manual hosts
- if(hostnum < hostcount)
- {
- if (!(p.server_addr = gg_dnslookup(gg, hosts[hostnum].hostname)))
- {
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Server hostname %s is invalid. Using default hostname provided by the network."), hosts[hostnum].hostname);
- gg_showpopup(gg, GG_PROTONAME, error, GG_POPUP_WARNING | GG_POPUP_ALLOW_MSGBOX);
- }
- else
- {
- p.server_port = hosts[hostnum].port;
- gg_netlog(gg, "gg_mainthread(%x): Connecting to manually specified host %s (%d.%d.%d.%d) and port %d.", gg,
- hosts[hostnum].hostname, LOBYTE(LOWORD(p.server_addr)), HIBYTE(LOWORD(p.server_addr)),
- LOBYTE(HIWORD(p.server_addr)), HIBYTE(HIWORD(p.server_addr)), p.server_port);
- }
- }
- else
- p.server_port = p.server_addr = 0;
-
- // Send login request
- if (!(sess = gg_login(&p, &gg->sock, &gg_failno)))
- {
- gg_broadcastnewstatus(gg, ID_STATUS_OFFLINE);
- // Check if connection attempt wasn't cancelled by the user
- if (gg->proto.m_iDesiredStatus != ID_STATUS_OFFLINE)
- {
- char error[128], *perror = NULL;
- // Lookup for error desciption
- if (errno == EACCES)
- {
- int i;
- for (i = 0; reason[i].type; i++) if (reason[i].type == gg_failno)
- {
- perror = Translate(reason[i].str);
- break;
- }
- }
- if (!perror)
- {
- mir_snprintf(error, sizeof(error), Translate("Connection cannot be established because of error:\n\t%s"), strerror(errno));
- perror = error;
- }
- gg_netlog(gg, "gg_mainthread(%x): %s", gg, perror);
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWCERRORS, GG_KEYDEF_SHOWCERRORS))
- gg_showpopup(gg, GG_PROTONAME, perror, GG_POPUP_ERROR | GG_POPUP_ALLOW_MSGBOX | GG_POPUP_ONCE);
-
- // Check if we should reconnect
- if ((gg_failno >= GG_FAILURE_RESOLVING && gg_failno != GG_FAILURE_PASSWORD && gg_failno != GG_FAILURE_INTRUDER && gg_failno != GG_FAILURE_UNAVAILABLE)
- && errno == EACCES
- && (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ARECONNECT, GG_KEYDEF_ARECONNECT) || (hostnum < hostcount - 1)))
- {
- DWORD dwInterval = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_RECONNINTERVAL, GG_KEYDEF_RECONNINTERVAL), dwResult;
- BOOL bRetry = TRUE;
-
- gg->hConnStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- dwResult = WaitForSingleObjectEx(gg->hConnStopEvent, dwInterval, TRUE);
- if ((dwResult == WAIT_OBJECT_0 && gg->proto.m_iDesiredStatus == ID_STATUS_OFFLINE)
- || (dwResult == WAIT_IO_COMPLETION && Miranda_Terminated()))
- bRetry = FALSE;
- CloseHandle(gg->hConnStopEvent);
- gg->hConnStopEvent = NULL;
-
- // Reconnect to the next server on the list
- if (bRetry)
- {
- if (hostnum < hostcount - 1) hostnum++;
- mir_free(p.status_descr);
- gg_broadcastnewstatus(gg, ID_STATUS_CONNECTING);
- goto retry;
- }
- }
- // We cannot do more about this
- EnterCriticalSection(&gg->modemsg_mutex);
- gg->proto.m_iDesiredStatus = ID_STATUS_OFFLINE;
- LeaveCriticalSection(&gg->modemsg_mutex);
- }
- else
- gg_netlog(gg, "gg_mainthread(%x)): Connection attempt cancelled by the user.", gg);
- }
- else
- {
- // Successfully connected
- logonTime = time(NULL);
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_KEY_LOGONTIME, logonTime);
- EnterCriticalSection(&gg->sess_mutex);
- gg->sess = sess;
- LeaveCriticalSection(&gg->sess_mutex);
- // Subscribe users status notifications
- gg_notifyall(gg);
- // Set startup status
- if (gg->proto.m_iDesiredStatus != status_gg2m(gg, p.status))
- gg_refreshstatus(gg, gg->proto.m_iDesiredStatus);
- else
- {
- gg_broadcastnewstatus(gg, gg->proto.m_iDesiredStatus);
- // Change status of the contact with our own UIN (if got yourself added to the contact list)
- gg_changecontactstatus(gg, p.uin, p.status, p.status_descr, 0, 0, 0, 0);
- }
- if (gg->check_first_conn) // First connection to the account
- {
- // Start search for user data
- gg_getinfo((PROTO_INTERFACE *)gg, NULL, 0);
- // Fetch user avatar
- gg_getuseravatar(gg);
- gg->check_first_conn = 0;
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // Main loop
- while(gg_isonline(gg))
- {
- // Connection broken/closed
- if (!(e = gg_watch_fd(gg->sess)))
- {
- gg_netlog(gg, "gg_mainthread(%x): Connection closed.", gg);
- EnterCriticalSection(&gg->sess_mutex);
- gg_free_session(gg->sess);
- gg->sess = NULL;
- LeaveCriticalSection(&gg->sess_mutex);
- break;
- }
- else
- gg_netlog(gg, "gg_mainthread(%x): Event: %s", gg, ggdebug_eventtype(e));
-
- switch(e->type)
- {
- // Client connected
- case GG_EVENT_CONN_SUCCESS:
- // Nada
- break;
-
- // Client disconnected or connection failure
- case GG_EVENT_CONN_FAILED:
- case GG_EVENT_DISCONNECT:
- EnterCriticalSection(&gg->sess_mutex);
- gg_free_session(gg->sess);
- gg->sess = NULL;
- LeaveCriticalSection(&gg->sess_mutex);
- break;
-
- // Client allowed to disconnect
- case GG_EVENT_DISCONNECT_ACK:
- // Send logoff
- gg_logoff(gg->sess);
- break;
-
- // Received ackowledge
- case GG_EVENT_ACK:
- if(e->event.ack.seq && e->event.ack.recipient)
- {
- ProtoBroadcastAck(GG_PROTO, gg_getcontact(gg, (DWORD)e->event.ack.recipient, 0, 0, NULL),
- ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) e->event.ack.seq, 0);
- }
- break;
-
- // Statuslist notify (deprecated)
- case GG_EVENT_NOTIFY:
- case GG_EVENT_NOTIFY_DESCR:
- {
- struct gg_notify_reply *n;
-
- n = (e->type == GG_EVENT_NOTIFY) ? e->event.notify : e->event.notify_descr.notify;
-
- for (; n->uin; n++)
- {
- char *descr = (e->type == GG_EVENT_NOTIFY_DESCR) ? e->event.notify_descr.descr : NULL;
- gg_changecontactstatus(gg, n->uin, n->status, descr, 0, n->remote_ip, n->remote_port, n->version);
- }
- break;
- }
- // Statuslist notify (version >= 6.0)
- case GG_EVENT_NOTIFY60:
- {
- uin_t uin = (uin_t)DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0);
- int i;
- for(i = 0; e->event.notify60[i].uin; i++) {
- if (e->event.notify60[i].uin == uin) continue;
- gg_changecontactstatus(gg, e->event.notify60[i].uin, e->event.notify60[i].status, e->event.notify60[i].descr,
- e->event.notify60[i].time, e->event.notify60[i].remote_ip, e->event.notify60[i].remote_port,
- e->event.notify60[i].version);
- gg_requestavatar(gg, gg_getcontact(gg, e->event.notify60[i].uin, 0, 0, NULL), 0);
- }
- break;
- }
-
- // Pubdir search reply && read own data reply
- case GG_EVENT_PUBDIR50_SEARCH_REPLY:
- case GG_EVENT_PUBDIR50_READ:
- case GG_EVENT_PUBDIR50_WRITE:
- {
- gg_pubdir50_t res = e->event.pubdir50;
- int i, count;
-
- if (e->type == GG_EVENT_PUBDIR50_SEARCH_REPLY)
- {
- gg_netlog(gg, "gg_mainthread(%x): Got user info.", gg);
- // Store next search UIN
- if (res->seq == GG_SEQ_SEARCH)
- gg->next_uin = gg_pubdir50_next(res);
- }
- else if (e->type == GG_EVENT_PUBDIR50_READ)
- {
- gg_netlog(gg, "gg_mainthread(%x): Got owner info.", gg);
- }
- else if (e->type == GG_EVENT_PUBDIR50_WRITE)
- {
- gg_netlog(gg, "gg_mainthread(%x): Public directory save succesful.", gg);
- // Update user details
- gg_getinfo((PROTO_INTERFACE *)gg, NULL, 0);
- }
-
- if ((count = gg_pubdir50_count(res)) > 0)
- {
- for (i = 0; i < count; i++)
- {
- // Loadup fields
- const char *__fmnumber = gg_pubdir50_get(res, i, GG_PUBDIR50_UIN);
- const char *__nick = gg_pubdir50_get(res, i, GG_PUBDIR50_NICKNAME);
- const char *__firstname = gg_pubdir50_get(res, i, GG_PUBDIR50_FIRSTNAME);
- const char *__lastname = gg_pubdir50_get(res, i, GG_PUBDIR50_LASTNAME);
- const char *__familyname = gg_pubdir50_get(res, i, GG_PUBDIR50_FAMILYNAME);
- const char *__birthyear = gg_pubdir50_get(res, i, GG_PUBDIR50_BIRTHYEAR);
- const char *__city = gg_pubdir50_get(res, i, GG_PUBDIR50_CITY);
- const char *__origincity = gg_pubdir50_get(res, i, GG_PUBDIR50_FAMILYCITY);
- const char *__gender = gg_pubdir50_get(res, i, GG_PUBDIR50_GENDER);
- const char *__status = gg_pubdir50_get(res, i, GG_PUBDIR50_STATUS);
- uin_t uin = __fmnumber ? atoi(__fmnumber) : 0;
-
- HANDLE hContact = (res->seq == GG_SEQ_CHINFO) ? NULL : gg_getcontact(gg, uin, 0, 0, NULL);
- gg_netlog(gg, "gg_mainthread(%x): Search result for uin %d, seq %d.", gg, uin, res->seq);
- if (res->seq == GG_SEQ_SEARCH)
- {
- char strFmt1[64];
- char strFmt2[64];
- GGSEARCHRESULT sr = {0};
-
- mir_snprintf(strFmt2, sizeof(strFmt2), "%s", (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, status_gg2m(gg, atoi(__status)), 0));
- if (__city)
- {
- mir_snprintf(strFmt1, sizeof(strFmt1), ", %s %s", Translate("City:"), __city);
- strncat(strFmt2, strFmt1, sizeof(strFmt2) - strlen(strFmt2));
- }
- if (__birthyear)
- {
- time_t t = time(NULL);
- struct tm *lt = localtime(&t);
- int br = atoi(__birthyear);
-
- if (br < (lt->tm_year + 1900) && br > 1900)
- {
- mir_snprintf(strFmt1, sizeof(strFmt1), ", %s %d", Translate("Age:"), (lt->tm_year + 1900) - br);
- strncat(strFmt2, strFmt1, sizeof(strFmt2) - strlen(strFmt2));
- }
- }
-
- sr.hdr.cbSize = sizeof(sr);
- sr.hdr.nick = (char *)__nick;
- sr.hdr.firstName = (char *)__firstname;
- sr.hdr.lastName = (char *)__lastname;
- sr.hdr.email = strFmt2;
- sr.hdr.id = _ultoa(uin, strFmt1, 10);
- sr.uin = uin;
-
- ProtoBroadcastAck(GG_PROTO, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) 1, (LPARAM)&sr);
- }
-
- if (((res->seq == GG_SEQ_INFO || res->seq == GG_SEQ_GETNICK) && hContact != NULL)
- || res->seq == GG_SEQ_CHINFO)
- {
- // Change nickname if it's not present
- if (__nick && (res->seq == GG_SEQ_GETNICK || res->seq == GG_SEQ_CHINFO))
- DBWriteContactSettingString(hContact, GG_PROTO, GG_KEY_NICK, __nick);
-
- if (__nick)
- DBWriteContactSettingString(hContact, GG_PROTO, "NickName", __nick);
- else if (res->seq == GG_SEQ_CHINFO)
- DBDeleteContactSetting(NULL, GG_PROTO, "NickName");
-
- // Change other info
- if (__city)
- DBWriteContactSettingString(hContact, GG_PROTO, "City", __city);
- else if (res->seq == GG_SEQ_CHINFO)
- DBDeleteContactSetting(NULL, GG_PROTO, "City");
-
- if (__firstname)
- DBWriteContactSettingString(hContact, GG_PROTO, "FirstName", __firstname);
- else if (res->seq == GG_SEQ_CHINFO)
- DBDeleteContactSetting(NULL, GG_PROTO, "FirstName");
-
- if (__lastname)
- DBWriteContactSettingString(hContact, GG_PROTO, "LastName", __lastname);
- else if (res->seq == GG_SEQ_CHINFO)
- DBDeleteContactSetting(NULL, GG_PROTO, "LastName");
-
- if (__familyname)
- DBWriteContactSettingString(hContact, GG_PROTO, "FamilyName", __familyname);
- else if (res->seq == GG_SEQ_CHINFO)
- DBDeleteContactSetting(NULL, GG_PROTO, "FamilyName");
-
- if (__origincity)
- DBWriteContactSettingString(hContact, GG_PROTO, "CityOrigin", __origincity);
- else if (res->seq == GG_SEQ_CHINFO)
- DBDeleteContactSetting(NULL, GG_PROTO, "CityOrigin");
-
- if (__birthyear)
- {
- time_t t = time(NULL);
- struct tm *lt = localtime(&t);
- int br = atoi(__birthyear);
- if (br > 0)
- {
- DBWriteContactSettingWord(hContact, GG_PROTO, "Age", (WORD)(lt->tm_year + 1900 - br));
- DBWriteContactSettingWord(hContact, GG_PROTO, "BirthYear", (WORD)br);
- }
- }
- else if (res->seq == GG_SEQ_CHINFO)
- {
- DBDeleteContactSetting(NULL, GG_PROTO, "Age");
- DBDeleteContactSetting(NULL, GG_PROTO, "BirthYear");
- }
-
- // Gadu-Gadu Male <-> Female
- if (__gender)
- {
- if (res->seq == GG_SEQ_CHINFO)
- DBWriteContactSettingByte(hContact, GG_PROTO, "Gender",
- (BYTE)(!strcmp(__gender, GG_PUBDIR50_GENDER_SET_MALE) ? 'M' :
- (!strcmp(__gender, GG_PUBDIR50_GENDER_SET_FEMALE) ? 'F' : '?')));
- else
- DBWriteContactSettingByte(hContact, GG_PROTO, "Gender",
- (BYTE)(!strcmp(__gender, GG_PUBDIR50_GENDER_MALE) ? 'M' :
- (!strcmp(__gender, GG_PUBDIR50_GENDER_FEMALE) ? 'F' : '?')));
- }
- else if (res->seq == GG_SEQ_CHINFO)
- {
- DBDeleteContactSetting(NULL, GG_PROTO, "Gender");
- }
-
- gg_netlog(gg, "gg_mainthread(%x): Setting user info for uin %d.", gg, uin);
- ProtoBroadcastAck(GG_PROTO, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
- }
- }
- }
- if (res->seq == GG_SEQ_SEARCH)
- ProtoBroadcastAck(GG_PROTO, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
- break;
- }
-
- // Status (deprecated)
- case GG_EVENT_STATUS:
- gg_changecontactstatus(gg, e->event.status.uin, e->event.status.status, e->event.status.descr, 0, 0, 0, 0);
- break;
-
- // Status (version >= 6.0)
- case GG_EVENT_STATUS60:
- {
- HANDLE hContact = gg_getcontact(gg, e->event.status60.uin, 0, 0, NULL);
- int oldstatus = DBGetContactSettingWord(hContact, GG_PROTO, GG_KEY_STATUS, (WORD)ID_STATUS_OFFLINE);
- uin_t uin = (uin_t)DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0);
-
- if (e->event.status60.uin == uin)
- {
- // Status was changed by the user simultaneously logged on using different Miranda account or IM client
- int iStatus = status_gg2m(gg, e->event.status60.status);
- CallProtoService(GG_PROTO, PS_SETAWAYMSG, iStatus, (LPARAM)e->event.status60.descr);
- CallProtoService(GG_PROTO, PS_SETSTATUS, iStatus, 0);
- }
-
- gg_changecontactstatus(gg, e->event.status60.uin, e->event.status60.status, e->event.status60.descr,
- e->event.status60.time, e->event.status60.remote_ip, e->event.status60.remote_port, e->event.status60.version);
-
- if (oldstatus == ID_STATUS_OFFLINE && DBGetContactSettingWord(hContact, GG_PROTO, GG_KEY_STATUS, (WORD)ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
- gg_requestavatar(gg, hContact, 0);
- }
- break;
-
- // Received userlist / or put info
- case GG_EVENT_USERLIST:
- switch (e->event.userlist.type)
- {
- case GG_USERLIST_GET_REPLY:
- if(e->event.userlist.reply)
- {
- gg_parsecontacts(gg, e->event.userlist.reply);
- MessageBox(
- NULL,
- Translate("List import successful."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
- }
- break;
-
- case GG_USERLIST_PUT_REPLY:
- if(gg->list_remove)
- MessageBox(
- NULL,
- Translate("List remove successful."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
- else
- MessageBox(
- NULL,
- Translate("List export successful."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
-
- break;
- }
- break;
-
- // Received message
- case GG_EVENT_MSG:
- // This is CTCP request
- if ((e->event.msg.msgclass & GG_CLASS_CTCP))
- {
- gg_dccconnect(gg, e->event.msg.sender);
- }
- // Check if not conference and block
- else if (!e->event.msg.recipients_count || gg->gc_enabled)
- {
- // Check if groupchat
- if(e->event.msg.recipients_count && gg->gc_enabled && !DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IGNORECONF, GG_KEYDEF_IGNORECONF))
- {
- char *chat = gg_gc_getchat(gg, e->event.msg.sender, e->event.msg.recipients, e->event.msg.recipients_count);
- if(chat)
- {
- char id[32];
- GCDEST gcdest = {GG_PROTO, chat, GC_EVENT_MESSAGE};
- GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
- time_t t = time(NULL);
-
- UIN2ID(e->event.msg.sender, id);
-
- gcevent.pszUID = id;
- gcevent.pszText = e->event.msg.message;
- gcevent.pszNick = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) gg_getcontact(gg, e->event.msg.sender, 1, 0, NULL), 0);
- gcevent.time = (!(e->event.msg.msgclass & GG_CLASS_OFFLINE) || e->event.msg.time > (t - timeDeviation)) ? t : e->event.msg.time;
- gcevent.dwFlags = GCEF_ADDTOLOG;
- gg_netlog(gg, "gg_mainthread(%x): Conference message to room %s & id %s.", gg, chat, id);
- CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
- }
- }
- // Check if not empty message ( who needs it? )
- else if (!e->event.msg.recipients_count && e->event.msg.message && *e->event.msg.message && strcmp(e->event.msg.message, "\xA0\0"))
- {
- CCSDATA ccs = {0};
- PROTORECVEVENT pre = {0};
- time_t t = time(NULL);
- ccs.szProtoService = PSR_MESSAGE;
- ccs.hContact = gg_getcontact(gg, e->event.msg.sender, 1, 0, NULL);
- ccs.lParam = (LPARAM)&pre;
- pre.timestamp = (!(e->event.msg.msgclass & GG_CLASS_OFFLINE) || e->event.msg.time > (t - timeDeviation)) ? t : e->event.msg.time;
- pre.szMessage = e->event.msg.message;
- CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs);
- }
-
- // RichEdit format included (image)
- if(e->event.msg.formats_length &&
- DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGRECEIVE, GG_KEYDEF_IMGRECEIVE) &&
- !(DBGetContactSettingDword(gg_getcontact(gg, e->event.msg.sender, 1, 0, NULL), "Ignore", "Mask1", 0) & IGNOREEVENT_MESSAGE))
- {
- char *formats = e->event.msg.formats;
- int len = 0, formats_len = e->event.msg.formats_length, add_ptr;
-
- while (len < formats_len)
- {
- add_ptr = sizeof(struct gg_msg_richtext_format);
- if (((struct gg_msg_richtext_format*)formats)->font & GG_FONT_IMAGE)
- {
- struct gg_msg_richtext_image *image = (struct gg_msg_richtext_image *)(formats + add_ptr);
- EnterCriticalSection(&gg->sess_mutex);
- gg_image_request(gg->sess, e->event.msg.sender, image->size, image->crc32);
- LeaveCriticalSection(&gg->sess_mutex);
-
- gg_netlog(gg, "gg_mainthread: image request sent!");
- add_ptr += sizeof(struct gg_msg_richtext_image);
- }
- if (((struct gg_msg_richtext_format*)formats)->font & GG_FONT_COLOR)
- add_ptr += sizeof(struct gg_msg_richtext_color);
- len += add_ptr;
- formats += add_ptr;
- }
- }
- }
- break;
-
- // Message sent from concurrent user session
- case GG_EVENT_MULTILOGON_MSG:
- if (e->event.multilogon_msg.recipients_count && gg->gc_enabled && !DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IGNORECONF, GG_KEYDEF_IGNORECONF))
- {
- char *chat = gg_gc_getchat(gg, e->event.multilogon_msg.sender, e->event.multilogon_msg.recipients, e->event.multilogon_msg.recipients_count);
- if (chat)
- {
- char id[32];
- DBVARIANT dbv;
- GCDEST gcdest = {GG_PROTO, chat, GC_EVENT_MESSAGE};
- GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
-
- UIN2ID(DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0), id);
-
- gcevent.pszUID = id;
- gcevent.pszText = e->event.multilogon_msg.message;
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_NICK, &dbv))
- gcevent.pszNick = dbv.pszVal;
- else
- gcevent.pszNick = Translate("Me");
- gcevent.time = e->event.multilogon_msg.time;
- gcevent.bIsMe = 1;
- gcevent.dwFlags = GCEF_ADDTOLOG;
- gg_netlog(gg, "gg_mainthread(%x): Sent conference message to room %s.", gg, chat);
- CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
- if (gcevent.pszNick == dbv.pszVal) DBFreeVariant(&dbv);
- }
- }
- else if (!e->event.multilogon_msg.recipients_count && e->event.multilogon_msg.message && *e->event.multilogon_msg.message
- && strcmp(e->event.multilogon_msg.message, "\xA0\0"))
- {
- DBEVENTINFO dbei = {0};
- dbei.cbSize = sizeof(dbei);
- dbei.szModule = GG_PROTO;
- dbei.timestamp = (DWORD)e->event.multilogon_msg.time;
- dbei.flags = DBEF_SENT;
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.cbBlob = (DWORD)strlen(e->event.multilogon_msg.message) + 1;
- dbei.pBlob = (PBYTE)e->event.multilogon_msg.message;
- CallService(MS_DB_EVENT_ADD, (WPARAM)gg_getcontact(gg, e->event.multilogon_msg.sender, 1, 0, NULL), (LPARAM)&dbei);
- }
- break;
-
- // Information on active concurrent sessions
- case GG_EVENT_MULTILOGON_INFO:
- {
- list_t l;
- int* iIndexes = NULL, i;
- gg_netlog(gg, "gg_mainthread(): Concurrent sessions count: %d.", e->event.multilogon_info.count);
- if (e->event.multilogon_info.count > 0)
- iIndexes = mir_calloc(e->event.multilogon_info.count * sizeof(int));
- EnterCriticalSection(&gg->sessions_mutex);
- for (l = gg->sessions; l; l = l->next)
- {
- struct gg_multilogon_session* sess = (struct gg_multilogon_session*)l->data;
- for (i = 0; i < e->event.multilogon_info.count; i++)
- {
- if (!memcmp(&sess->id, &e->event.multilogon_info.sessions[i].id, sizeof(gg_multilogon_id_t)) && iIndexes)
- {
- iIndexes[i]++;
- break;
- }
- }
- mir_free(sess->name);
- mir_free(sess);
- }
- list_destroy(gg->sessions, 0);
- gg->sessions = NULL;
- for (i = 0; i < e->event.multilogon_info.count; i++)
- {
- struct gg_multilogon_session* sess = mir_alloc(sizeof(struct gg_multilogon_session));
- memcpy(sess, &e->event.multilogon_info.sessions[i], sizeof(struct gg_multilogon_session));
- sess->name = mir_strdup(*e->event.multilogon_info.sessions[i].name != '\0'
- ? e->event.multilogon_info.sessions[i].name
- : Translate("Unknown client"));
- list_add(&gg->sessions, sess, 0);
- }
- LeaveCriticalSection(&gg->sessions_mutex);
- gg_sessions_updatedlg(gg);
- if (ServiceExists(MS_POPUP_ADDPOPUPCLASS))
- {
- const char* szText = time(NULL) - logonTime > 3
- ? Translate("You have logged in at another location")
- : Translate("You are logged in at another location");
- for (i = 0; i < e->event.multilogon_info.count; i++)
- {
- char szMsg[MAX_SECONDLINE];
- if (iIndexes && iIndexes[i]) continue;
- mir_snprintf(szMsg, SIZEOF(szMsg), "%s (%s)", szText,
- *e->event.multilogon_info.sessions[i].name != '\0'
- ? e->event.multilogon_info.sessions[i].name
- : Translate("Unknown client"));
- gg_showpopup(gg, GG_PROTONAME, szMsg, GG_POPUP_MULTILOGON);
- }
- }
- mir_free(iIndexes);
- }
- break;
-
- // Image reply sent
- case GG_EVENT_IMAGE_REPLY:
- // Get rid of empty image
- if(e->event.image_reply.size && e->event.image_reply.image)
- {
- HANDLE hContact = gg_getcontact(gg, e->event.image_reply.sender, 1, 0, NULL);
- void *img = (void *)gg_img_loadpicture(gg, e, 0);
-
- if (!img)
- break;
-
- if(DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGMETHOD, GG_KEYDEF_IMGMETHOD) == 1 || gg_img_opened(gg, e->event.image_reply.sender))
- {
- gg_img_display(gg, hContact, img);
- }
- else if(DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGMETHOD, GG_KEYDEF_IMGMETHOD) == 2)
- {
- gg_img_displayasmsg(gg, hContact, img);
- }
- else
- {
- CLISTEVENT cle = {0};
- char service[128];
- mir_snprintf(service, sizeof(service), GGS_RECVIMAGE, GG_PROTO);
-
- cle.cbSize = sizeof(cle);
- cle.hContact = hContact;
- cle.hIcon = LoadIconEx("image", FALSE);
- cle.flags = CLEF_URGENT;
- cle.hDbEvent = (HANDLE)"img";
- cle.lParam = (LPARAM)img;
- cle.pszService = service;
- cle.pszTooltip = Translate("Incoming image");
- CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle);
- ReleaseIconEx("image", FALSE);
- }
- }
- break;
-
- // Image send request
- case GG_EVENT_IMAGE_REQUEST:
- gg_img_sendonrequest(gg, e);
- break;
-
- // Incoming direct connection
- case GG_EVENT_DCC7_NEW:
- {
- struct gg_dcc7 *dcc7 = e->event.dcc7_new;
- gg_netlog(gg, "gg_mainthread(%x): Incoming direct connection.", gg);
- dcc7->contact = gg_getcontact(gg, dcc7->peer_uin, 0, 0, NULL);
-
- // Check if user is on the list and if it is my uin
- if (!dcc7->contact || DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, -1) != dcc7->uin) {
- gg_dcc7_free(dcc7);
- e->event.dcc7_new = NULL;
- break;
- }
-
- // Add to waiting transfers
- EnterCriticalSection(&gg->ft_mutex);
- list_add(&gg->transfers, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
-
- //////////////////////////////////////////////////
- // Add file recv request
- {
- CCSDATA ccs;
- PROTORECVEVENT pre;
- char *szBlob;
- char *szFilename = dcc7->filename;
- char *szMsg = dcc7->filename;
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, File ack filename \"%s\" size %d.", gg, dcc7->peer_uin,
- dcc7->filename, dcc7->size);
- // Make new ggtransfer struct
- szBlob = (char *)malloc(sizeof(DWORD) + strlen(szFilename) + strlen(szMsg) + 2);
- // Store current dcc
- *(PDWORD)szBlob = (DWORD)dcc7;
- // Store filename
- strcpy(szBlob + sizeof(DWORD), szFilename);
- // Store description
- strcpy(szBlob + sizeof(DWORD) + strlen(szFilename) + 1, szMsg);
- ccs.szProtoService = PSR_FILE;
- ccs.hContact = dcc7->contact;
- ccs.wParam = 0;
- ccs.lParam = (LPARAM)&pre;
- pre.flags = 0;
- pre.timestamp = time(NULL);
- pre.szMessage = szBlob;
- pre.lParam = 0;
- CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs);
- free(szBlob);
- }
- e->event.dcc7_new = NULL;
- }
- break;
-
- // Direct connection rejected
- case GG_EVENT_DCC7_REJECT:
- {
- struct gg_dcc7 *dcc7 = e->event.dcc7_reject.dcc7;
- if (dcc7->type == GG_SESSION_DCC7_SEND)
- {
- gg_netlog(gg, "gg_mainthread(%x): File transfer denied by client %d (reason = %d).", gg, dcc7->peer_uin, e->event.dcc7_reject.reason);
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DENIED, dcc7, 0);
-
- // Remove from watches and free
- EnterCriticalSection(&gg->ft_mutex);
- list_remove(&gg->watches, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
- gg_dcc7_free(dcc7);
- }
- else
- {
- gg_netlog(gg, "gg_mainthread(%x): File transfer aborted by client %d.", gg, dcc7->peer_uin);
-
- // Remove transfer from waiting list
- EnterCriticalSection(&gg->ft_mutex);
- list_remove(&gg->transfers, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
- }
- }
- break;
-
- // Direct connection error
- case GG_EVENT_DCC7_ERROR:
- {
- struct gg_dcc7 *dcc7 = e->event.dcc7_error_ex.dcc7;
- switch (e->event.dcc7_error)
- {
- case GG_ERROR_DCC7_HANDSHAKE:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, Handshake error.", gg, dcc7 ? dcc7->peer_uin : 0);
- break;
- case GG_ERROR_DCC7_NET:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, Network error.", gg, dcc7 ? dcc7->peer_uin : 0);
- break;
- case GG_ERROR_DCC7_FILE:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, File read/write error.", gg, dcc7 ? dcc7->peer_uin : 0);
- break;
- case GG_ERROR_DCC7_EOF:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, End of file/connection error.", gg, dcc7 ? dcc7->peer_uin : 0);
- break;
- case GG_ERROR_DCC7_REFUSED:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, Connection refused error.", gg, dcc7 ? dcc7->peer_uin : 0);
- break;
- case GG_ERROR_DCC7_RELAY:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, Relay connection error.", gg, dcc7 ? dcc7->peer_uin : 0);
- break;
- default:
- gg_netlog(gg, "gg_mainthread(%x): Client: %d, Unknown error.", gg, dcc7 ? dcc7->peer_uin : 0);
- }
- if (!dcc7) break;
-
- // Remove from watches
- list_remove(&gg->watches, dcc7, 0);
-
- // Close file & fail
- if (dcc7->file_fd != -1)
- {
- _close(dcc7->file_fd);
- dcc7->file_fd = -1;
- }
-
- if (dcc7->contact)
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
-
- // Free dcc
- gg_dcc7_free(dcc7);
- }
- break;
-
- case GG_EVENT_XML_ACTION:
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)) {
- HXML hXml;
- TCHAR *xmlAction;
- TCHAR *tag;
-
- xmlAction = gg_a2t(e->event.xml_action.data);
- tag = gg_a2t("events");
- hXml = xi.parseString(xmlAction, 0, tag);
-
- if (hXml != NULL) {
- HXML node;
- char *type, *sender;
-
- mir_free(tag);
- tag = gg_a2t("event/type");
- node = xi.getChildByPath(hXml, tag, 0);
- type = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
-
- mir_free(tag);
- tag = gg_a2t("event/sender");
- node = xi.getChildByPath(hXml, tag, 0);
- sender = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
- gg_netlog(gg, "gg_mainthread(%x): XML Action type: %s.", gg, type != NULL ? type : "unknown");
- // Avatar change notify
- if (type != NULL && !strcmp(type, "28")) {
- gg_netlog(gg, "gg_mainthread(%x): Client %s changed his avatar.", gg, sender);
- gg_requestavatar(gg, gg_getcontact(gg, atoi(sender), 0, 0, NULL), 0);
- }
- mir_free(type);
- mir_free(sender);
- xi.destroyNode(hXml);
- }
- mir_free(tag);
- mir_free(xmlAction);
- }
- break;
-
- case GG_EVENT_TYPING_NOTIFICATION:
- {
- HANDLE hContact = gg_getcontact(gg, e->event.typing_notification.uin, 0, 0, NULL);
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_mainthread(%x): Typing notification from %d (%d).", gg,
- e->event.typing_notification.uin, e->event.typing_notification.length);
-#endif
- CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact,
- e->event.typing_notification.length > 0 ? 7 : PROTOTYPE_CONTACTTYPING_OFF);
- }
- break;
- }
- // Free event struct
- gg_free_event(e);
- }
-
- gg_broadcastnewstatus(gg, ID_STATUS_OFFLINE);
- gg_setalloffline(gg);
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_KEY_LOGONTIME, 0);
-
- // If it was unwanted disconnection reconnect
- if(gg->proto.m_iDesiredStatus != ID_STATUS_OFFLINE
- && DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ARECONNECT, GG_KEYDEF_ARECONNECT))
- {
- gg_netlog(gg, "gg_mainthread(%x): Unintentional disconnection detected. Going to reconnect...", gg);
- hostnum = 0;
- gg_broadcastnewstatus(gg, ID_STATUS_CONNECTING);
- mir_free(p.status_descr);
- goto retry;
- }
-
- mir_free(p.password);
- mir_free(p.status_descr);
-
- // Destroy concurrent sessions list
- {
- list_t l;
- EnterCriticalSection(&gg->sessions_mutex);
- for (l = gg->sessions; l; l = l->next)
- {
- struct gg_multilogon_session* sess = (struct gg_multilogon_session*)l->data;
- mir_free(sess->name);
- mir_free(sess);
- }
- list_destroy(gg->sessions, 0);
- gg->sessions = NULL;
- LeaveCriticalSection(&gg->sessions_mutex);
- }
-
- // Stop dcc server
- gg->pth_dcc.dwThreadId = 0;
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_mainthread(%x): Waiting until DCC Server Thread finished, if needed.", gg);
-#endif
- gg_threadwait(gg, &gg->pth_dcc);
-
- gg_netlog(gg, "gg_mainthread(%x): Server Thread Ending", gg);
- return;
-}
-
-////////////////////////////////////////////////////////////
-// Change status function
-void gg_broadcastnewstatus(GGPROTO *gg, int newStatus)
-{
- int oldStatus;
-
- EnterCriticalSection(&gg->modemsg_mutex);
- oldStatus = gg->proto.m_iStatus;
- if(oldStatus == newStatus)
- {
- LeaveCriticalSection(&gg->modemsg_mutex);
- return;
- }
- gg->proto.m_iStatus = newStatus;
- LeaveCriticalSection(&gg->modemsg_mutex);
-
- ProtoBroadcastAck(GG_PROTO, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, newStatus);
-
- gg_netlog(gg, "gg_broadcastnewstatus(): Broadcast new status: %d.", newStatus);
-}
-
-////////////////////////////////////////////////////////////
-// When contact is deleted
-int gg_contactdeleted(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- HANDLE hContact = (HANDLE) wParam;
- uin_t uin; int type;
- DBVARIANT dbv;
-
- uin = (uin_t)DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0);
- type = DBGetContactSettingByte(hContact, GG_PROTO, "ChatRoom", 0);
-
- // Terminate conference if contact is deleted
- if(type && !DBGetContactSetting(hContact, GG_PROTO, "ChatRoomID", &dbv) && gg->gc_enabled)
- {
- GCDEST gcdest = {GG_PROTO, dbv.pszVal, GC_EVENT_CONTROL};
- GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
- GGGC *chat = gg_gc_lookup(gg, dbv.pszVal);
-
- gg_netlog(gg, "gg_gc_event(): Terminating chat %x, id %s from contact list...", chat, dbv.pszVal);
- if(chat)
- {
- // Destroy chat entry
- free(chat->recipients);
- list_remove(&gg->chats, chat, 1);
- // Terminate chat window / shouldn't cascade entry is deleted
- CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gcevent);
- CallServiceSync(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gcevent);
- }
-
- DBFreeVariant(&dbv);
- return 0;
- }
-
- if(uin && gg_isonline(gg))
- {
- EnterCriticalSection(&gg->sess_mutex);
- gg_remove_notify_ex(gg->sess, uin, GG_USER_NORMAL);
- LeaveCriticalSection(&gg->sess_mutex);
- }
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////
-// When db settings changed
-int gg_dbsettingchanged(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
- HANDLE hContact = (HANDLE) wParam;
- char *szProto = NULL;
-
- // Check if the contact is NULL or we are not online
- if (!gg_isonline(gg))
- return 0;
-
- // If contact has been blocked
- if (!strcmp(cws->szModule, GG_PROTO) && !strcmp(cws->szSetting, GG_KEY_BLOCK))
- {
- gg_notifyuser(gg, hContact, 1);
- return 0;
- }
-
- // Contact is being renamed
- if(gg->gc_enabled && !strcmp(cws->szModule, GG_PROTO) && !strcmp(cws->szSetting, GG_KEY_NICK)
- && cws->value.pszVal)
- {
- // Groupchat window contact is being renamed
- DBVARIANT dbv;
- int type = DBGetContactSettingByte(hContact, GG_PROTO, "ChatRoom", 0);
- if(type && !DBGetContactSetting(hContact, GG_PROTO, "ChatRoomID", &dbv))
- {
- // Most important... check redundancy (fucking cascading)
- static int cascade = 0;
- if (!cascade && dbv.pszVal)
- {
- GCDEST gcdest = {GG_PROTO, dbv.pszVal, GC_EVENT_CHANGESESSIONAME};
- GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
- gcevent.pszText = cws->value.pszVal;
- gg_netlog(gg, "gg_dbsettingchanged(): Conference %s was renamed to %s.", dbv.pszVal, cws->value.pszVal);
- // Mark cascading
- /* FIXME */ cascade = 1;
- CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
- /* FIXME */ cascade = 0;
- }
- DBFreeVariant(&dbv);
- }
- else
- // Change contact name on all chats
- gg_gc_changenick(gg, hContact, cws->value.pszVal);
- }
-
- // Contact list changes
- if (!strcmp(cws->szModule, "CList"))
- {
- // If name changed... change nick
- if (!strcmp(cws->szSetting, "MyHandle") && cws->value.type == DBVT_ASCIIZ && cws->value.pszVal)
- DBWriteContactSettingString(hContact, GG_PROTO, GG_KEY_NICK, cws->value.pszVal);
-
- // If not on list changed
- if (!strcmp(cws->szSetting, "NotOnList"))
- {
- if(DBGetContactSettingByte(hContact, "CList", "Hidden", 0))
- return 0;
- // Notify user normally this time if added to the list permanently
- if(cws->value.type == DBVT_DELETED || (cws->value.type == DBVT_BYTE && cws->value.bVal == 0))
- gg_notifyuser(gg, hContact, 1);
- }
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////
-// All users set offline
-void gg_setalloffline(GGPROTO *gg)
-{
- HANDLE hContact;
- char *szProto;
-
- gg_netlog(gg, "gg_setalloffline(): Setting buddies offline");
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_STATUS, ID_STATUS_OFFLINE);
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
- while (hContact)
- {
- szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if(szProto != NULL && !strcmp(szProto, GG_PROTO))
- {
- DBWriteContactSettingWord(hContact, GG_PROTO, GG_KEY_STATUS, ID_STATUS_OFFLINE);
- // Clear IP and port settings
- DBDeleteContactSetting(hContact, GG_PROTO, GG_KEY_CLIENTIP);
- DBDeleteContactSetting(hContact, GG_PROTO, GG_KEY_CLIENTPORT);
- // Delete status descr
- DBDeleteContactSetting(hContact, "CList", GG_KEY_STATUSDESCR);
- }
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
- }
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_setalloffline(): End");
-#endif
-}
-
-////////////////////////////////////////////////////////////
-// All users set offline
-void gg_notifyuser(GGPROTO *gg, HANDLE hContact, int refresh)
-{
- uin_t uin;
- if (!hContact) return;
- if (gg_isonline(gg) && (uin = (uin_t)DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0)))
- {
- // Check if user should be invisible
- // Or be blocked ?
- if ((DBGetContactSettingWord(hContact, GG_PROTO, GG_KEY_APPARENT, (WORD) ID_STATUS_ONLINE) == ID_STATUS_OFFLINE) ||
- DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
- {
- EnterCriticalSection(&gg->sess_mutex);
- if (refresh)
- {
- gg_remove_notify_ex(gg->sess, uin, GG_USER_NORMAL);
- gg_remove_notify_ex(gg->sess, uin, GG_USER_BLOCKED);
- }
-
- gg_add_notify_ex(gg->sess, uin, GG_USER_OFFLINE);
- LeaveCriticalSection(&gg->sess_mutex);
- }
- else if (DBGetContactSettingByte(hContact, GG_PROTO, GG_KEY_BLOCK, 0))
- {
- EnterCriticalSection(&gg->sess_mutex);
- if (refresh)
- {
- gg_remove_notify_ex(gg->sess, uin, GG_USER_OFFLINE);
- }
-
- gg_add_notify_ex(gg->sess, uin, GG_USER_BLOCKED);
- LeaveCriticalSection(&gg->sess_mutex);
- }
- else
- {
- EnterCriticalSection(&gg->sess_mutex);
- if (refresh)
- {
- gg_remove_notify_ex(gg->sess, uin, GG_USER_BLOCKED);
- }
-
- gg_add_notify_ex(gg->sess, uin, GG_USER_NORMAL);
- LeaveCriticalSection(&gg->sess_mutex);
- }
- }
-}
-void gg_notifyall(GGPROTO *gg)
-{
- HANDLE hContact;
- char *szProto;
- int count = 0, cc = 0;
- uin_t *uins;
- char *types;
-
- gg_netlog(gg, "gg_notifyall(): Subscribing notification to all users");
- // Readup count
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
- while (hContact)
- {
- szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if (szProto != NULL && !strcmp(szProto, GG_PROTO)) count ++;
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
- }
-
- // Readup list
- /* FIXME: If we have nothing on the list but we omit gg_notify_ex we have problem with receiving any contacts */
- if (count == 0)
- {
- if(gg_isonline(gg))
- {
- EnterCriticalSection(&gg->sess_mutex);
- gg_notify_ex(gg->sess, NULL, NULL, 0);
- LeaveCriticalSection(&gg->sess_mutex);
- }
- return;
- }
- uins = calloc(sizeof(uin_t), count);
- types = calloc(sizeof(char), count);
-
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
- while (hContact && cc < count)
- {
- szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if (szProto != NULL && !strcmp(szProto, GG_PROTO) && (uins[cc] = DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0)))
- {
- if ((DBGetContactSettingWord(hContact, GG_PROTO, GG_KEY_APPARENT, (WORD) ID_STATUS_ONLINE) == ID_STATUS_OFFLINE) ||
- DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
- types[cc] = GG_USER_OFFLINE;
- else if (DBGetContactSettingByte(hContact, GG_PROTO, GG_KEY_BLOCK, 0))
- types[cc] = GG_USER_BLOCKED;
- else
- types[cc] = GG_USER_NORMAL;
- cc ++;
- }
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
- }
- if (cc < count) count = cc;
-
- // Send notification
- if (gg_isonline(gg))
- {
- EnterCriticalSection(&gg->sess_mutex);
- gg_notify_ex(gg->sess, uins, types, count);
- LeaveCriticalSection(&gg->sess_mutex);
- }
-
- // Free variables
- free(uins); free(types);
-}
-
-////////////////////////////////////////////////////////////
-// Get contact by uin
-HANDLE gg_getcontact(GGPROTO *gg, uin_t uin, int create, int inlist, char *szNick)
-{
- HANDLE hContact;
- char *szProto;
-
- // Look for contact in DB
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
- while (hContact)
- {
- szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if(szProto != NULL && !strcmp(szProto, GG_PROTO))
- {
- if ((uin_t)DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0) == uin
- && DBGetContactSettingByte(hContact, GG_PROTO, "ChatRoom", 0) == 0)
- {
- if(inlist)
- {
- DBDeleteContactSetting(hContact, "CList", "NotOnList");
- DBDeleteContactSetting(hContact, "CList", "Hidden");
- }
- return hContact;
- }
- }
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
- }
- if (!create) return NULL;
-
- hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
-
- if (!hContact)
- {
- gg_netlog(gg, "gg_getcontact(): Failed to create Gadu-Gadu contact %s", szNick);
- return NULL;
- }
-
- if(CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) GG_PROTO) != 0)
- {
- // For some reason we failed to register the protocol for this contact
- CallService(MS_DB_CONTACT_DELETE, (WPARAM) hContact, 0);
- gg_netlog(gg, "Failed to register GG contact %d", uin);
- return NULL;
- }
-
- gg_netlog(gg, "gg_getcontact(): Added buddy: %d", uin);
- if (!inlist)
- {
- DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
- //DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
- }
-
- DBWriteContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, (DWORD) uin);
- DBWriteContactSettingWord(hContact, GG_PROTO, GG_KEY_STATUS, ID_STATUS_OFFLINE);
-
- // If nick specified use it
- if(szNick)
- DBWriteContactSettingString(hContact, GG_PROTO, GG_KEY_NICK, szNick);
- else if(gg_isonline(gg))
- {
- gg_pubdir50_t req;
-
- // Search for that nick
- if(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH))
- {
- // Add uin and search it
- gg_pubdir50_add(req, GG_PUBDIR50_UIN, ditoa(uin));
- gg_pubdir50_seq_set(req, GG_SEQ_GETNICK);
- EnterCriticalSection(&gg->sess_mutex);
- gg_pubdir50(gg->sess, req);
- LeaveCriticalSection(&gg->sess_mutex);
- gg_pubdir50_free(req);
- DBWriteContactSettingString(hContact, GG_PROTO, GG_KEY_NICK, ditoa(uin));
- gg_netlog(gg, "gg_getcontact(): Search for nick on uin: %d", uin);
- }
- }
-
- // Add to notify list and pull avatar for the new contact
- if(gg_isonline(gg))
- {
- PROTO_AVATAR_INFORMATIONT pai = {0};
-
- EnterCriticalSection(&gg->sess_mutex);
- gg_add_notify_ex(gg->sess, uin, (char)(inlist ? GG_USER_NORMAL : GG_USER_OFFLINE));
- LeaveCriticalSection(&gg->sess_mutex);
-
- pai.cbSize = sizeof(pai);
- pai.hContact = hContact;
- gg_getavatarinfo(gg, (WPARAM)GAIF_FORCE, (LPARAM)&pai);
-
- // Change status of the contact with our own UIN (if got yourself added to the contact list)
- if (DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0) == uin)
- {
- char *szMsg;
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg_getstatusmsg(gg, gg->proto.m_iStatus));
- LeaveCriticalSection(&gg->modemsg_mutex);
- gg_changecontactstatus(gg, uin, status_m2gg(gg, gg->proto.m_iStatus, szMsg != NULL), szMsg, 0, 0, 0, 0);
- mir_free(szMsg);
- }
- }
-
- // TODO server side list & add buddy
- return hContact;
-}
-
-////////////////////////////////////////////////////////////
-// Status conversion
-int status_m2gg(GGPROTO *gg, int status, int descr)
-{
- // check frends only
- int mask = DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_FRIENDSONLY, GG_KEYDEF_FRIENDSONLY) ? GG_STATUS_FRIENDS_MASK : 0;
-
- if(descr)
- {
- switch(status)
- {
- case ID_STATUS_OFFLINE:
- return GG_STATUS_NOT_AVAIL_DESCR | mask;
-
- case ID_STATUS_ONLINE:
- return GG_STATUS_AVAIL_DESCR | mask;
-
- case ID_STATUS_AWAY:
- return GG_STATUS_BUSY_DESCR | mask;
-
- case ID_STATUS_DND:
- return GG_STATUS_DND_DESCR | mask;
-
- case ID_STATUS_FREECHAT:
- return GG_STATUS_FFC_DESCR | mask;
-
- case ID_STATUS_INVISIBLE:
- return GG_STATUS_INVISIBLE_DESCR | mask;
-
- default:
- return GG_STATUS_BUSY_DESCR | mask;
- }
- }
- else
- {
- switch(status)
- {
- case ID_STATUS_OFFLINE:
- return GG_STATUS_NOT_AVAIL | mask;
-
- case ID_STATUS_ONLINE:
- return GG_STATUS_AVAIL | mask;
-
- case ID_STATUS_AWAY:
- return GG_STATUS_BUSY | mask;
-
- case ID_STATUS_DND:
- return GG_STATUS_DND | mask;
-
- case ID_STATUS_FREECHAT:
- return GG_STATUS_FFC | mask;
-
- case ID_STATUS_INVISIBLE:
- return GG_STATUS_INVISIBLE | mask;
-
- default:
- return GG_STATUS_BUSY | mask;
- }
- }
-}
-int status_gg2m(GGPROTO *gg, int status)
-{
- // ignore additional flags
- status = GG_S(status);
-
- // when user has status description but is offline (show it invisible)
- if(status == GG_STATUS_NOT_AVAIL_DESCR && DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWINVISIBLE, GG_KEYDEF_SHOWINVISIBLE))
- return ID_STATUS_INVISIBLE;
-
- // rest of cases
- switch(status)
- {
- case GG_STATUS_NOT_AVAIL:
- case GG_STATUS_NOT_AVAIL_DESCR:
- return ID_STATUS_OFFLINE;
-
- case GG_STATUS_AVAIL:
- case GG_STATUS_AVAIL_DESCR:
- return ID_STATUS_ONLINE;
-
- case GG_STATUS_BUSY:
- case GG_STATUS_BUSY_DESCR:
- return ID_STATUS_AWAY;
-
- case GG_STATUS_DND:
- case GG_STATUS_DND_DESCR:
- return ID_STATUS_DND;
-
- case GG_STATUS_FFC:
- case GG_STATUS_FFC_DESCR:
- return ID_STATUS_FREECHAT;
-
- case GG_STATUS_INVISIBLE:
- case GG_STATUS_INVISIBLE_DESCR:
- return ID_STATUS_INVISIBLE;
-
- case GG_STATUS_BLOCKED:
- return ID_STATUS_NA;
-
- default:
- return ID_STATUS_OFFLINE;
- }
-}
-
-////////////////////////////////////////////////////////////
-// Called when contact status is changed
-void gg_changecontactstatus(GGPROTO *gg, uin_t uin, int status, const char *idescr, int time, uint32_t remote_ip, uint16_t remote_port, uint32_t version)
-{
- HANDLE hContact = gg_getcontact(gg, uin, 0, 0, NULL);
-
- // Check if contact is on list
- if (!hContact) return;
-
- // Write contact status
- DBWriteContactSettingWord(hContact, GG_PROTO, GG_KEY_STATUS, (WORD)status_gg2m(gg, status));
-
- // Check if there's description and if it's not empty
- if(idescr && *idescr)
- {
- gg_netlog(gg, "gg_changecontactstatus(): Saving for %d status descr \"%s\".", uin, idescr);
- DBWriteContactSettingString(hContact, "CList", GG_KEY_STATUSDESCR, idescr);
- }
- else
- // Remove status if there's nothing
- DBDeleteContactSetting(hContact, "CList", GG_KEY_STATUSDESCR);
-
- // Store contact ip and port
- if(remote_ip) DBWriteContactSettingDword(hContact, GG_PROTO, GG_KEY_CLIENTIP, (DWORD) swap32(remote_ip));
- if(remote_port) DBWriteContactSettingWord(hContact, GG_PROTO, GG_KEY_CLIENTPORT, (WORD) remote_port);
- if(version)
- {
- char sversion[48];
- DBWriteContactSettingDword(hContact, GG_PROTO, GG_KEY_CLIENTVERSION, (DWORD) version);
- mir_snprintf(sversion, sizeof(sversion), "%sGadu-Gadu %s", (version & 0x00ffffff) > 0x2b ? "Nowe " : "", gg_version2string(version));
- DBWriteContactSettingString(hContact, GG_PROTO, "MirVer", sversion);
- }
-}
-
-////////////////////////////////////////////////////////////
-// Returns GG client version string from packet version
-const char *gg_version2string(int v)
-{
- const char *pstr = "???";
- v &= 0x00ffffff;
- switch(v)
- {
- case 0x2e:
- pstr = "8.0 build 8283"; break;
- case 0x2d:
- pstr = "8.0 build 4881"; break;
- case 0x2b:
- pstr = "< 8.0"; break;
- case 0x2a:
- pstr = "7.7 build 3315"; break;
- case 0x29:
- pstr = "7.6 build 1688"; break;
- case 0x28:
- pstr = "7.5 build 2201"; break;
- case 0x27:
- pstr = "7.0 build 22"; break;
- case 0x26:
- pstr = "7.0 build 20"; break;
- case 0x25:
- pstr = "7.0 build 1"; break;
- case 0x24:
- pstr = "6.1 (155) / 7.6 (1359)"; break;
- case 0x22:
- pstr = "6.0 build 140"; break;
- case 0x21:
- pstr = "6.0 build 133"; break;
- case 0x20:
- pstr = "6.0b"; break;
- case 0x1e:
- pstr = "5.7b build 121"; break;
- case 0x1c:
- pstr = "5.7b"; break;
- case 0x1b:
- pstr = "5.0.5"; break;
- case 0x19:
- pstr = "5.0.3"; break;
- case 0x18:
- pstr = "5.0.0-1"; break;
- case 0x17:
- pstr = "4.9.2"; break;
- case 0x16:
- pstr = "4.9.1"; break;
- case 0x15:
- pstr = "4.8.9"; break;
- case 0x14:
- pstr = "4.8.1-3"; break;
- case 0x11:
- pstr = "4.6.1-10"; break;
- case 0x10:
- pstr = "4.5.15-22"; break;
- case 0x0f:
- pstr = "4.5.12"; break;
- case 0x0b:
- pstr = "4.0.25-30"; break;
- default:
- if (v < 0x0b)
- pstr = "< 4.0.25";
- else if (v > 0x2e)
- pstr = ">= 8.0";
- break;
- }
- return pstr;
-}
diff --git a/protocols/Gadu-Gadu/core.cpp b/protocols/Gadu-Gadu/core.cpp
new file mode 100644
index 0000000000..735b3536bc
--- /dev/null
+++ b/protocols/Gadu-Gadu/core.cpp
@@ -0,0 +1,1765 @@
+////////////////////////////////////////////////////////////////////////////////
+// Gadu-Gadu Plugin for Miranda IM
+//
+// Copyright (c) 2003-2009 Adam Strzelecki <ono+miranda@java.pl>
+// Copyright (c) 2009-2012 Bartosz Bia³ek
+//
+// 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 "gg.h"
+#include <errno.h>
+#include <io.h>
+
+////////////////////////////////////////////////////////////
+// Swap bits in DWORD
+uint32_t swap32(uint32_t x)
+{
+ return (uint32_t)
+ (((x & (uint32_t) 0x000000ffU) << 24) |
+ ((x & (uint32_t) 0x0000ff00U) << 8) |
+ ((x & (uint32_t) 0x00ff0000U) >> 8) |
+ ((x & (uint32_t) 0xff000000U) >> 24));
+}
+
+////////////////////////////////////////////////////////////
+// Is online function
+
+int GGPROTO::isonline()
+{
+ mir_cslock lck(sess_mutex);
+ return (sess != NULL);
+}
+
+////////////////////////////////////////////////////////////
+// Send disconnect request and wait for server thread to die
+void GGPROTO::disconnect()
+{
+ // If main loop then send disconnect request
+ if (isonline())
+ {
+ // Fetch proper status msg
+ char *szMsg = NULL;
+
+ // Loadup status
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_LEAVESTATUSMSG, GG_KEYDEF_LEAVESTATUSMSG))
+ {
+ DBVARIANT dbv;
+ switch (db_get_w(NULL, m_szModuleName, GG_KEY_LEAVESTATUS, GG_KEYDEF_LEAVESTATUS)) {
+ case ID_STATUS_ONLINE:
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(modemsg.online);
+ LeaveCriticalSection(&modemsg_mutex);
+ if (!szMsg && !db_get_s(NULL, "SRAway", gg_status2db(ID_STATUS_ONLINE, "Default"), &dbv, DBVT_ASCIIZ)) {
+ if (dbv.pszVal && *(dbv.pszVal))
+ szMsg = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case ID_STATUS_AWAY:
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(modemsg.away);
+ LeaveCriticalSection(&modemsg_mutex);
+ if (!szMsg && !db_get_s(NULL, "SRAway", gg_status2db(ID_STATUS_AWAY, "Default"), &dbv, DBVT_ASCIIZ)) {
+ if (dbv.pszVal && *(dbv.pszVal))
+ szMsg = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case ID_STATUS_DND:
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(modemsg.dnd);
+ LeaveCriticalSection(&modemsg_mutex);
+ if (!szMsg && !db_get_s(NULL, "SRAway", gg_status2db(ID_STATUS_DND, "Default"), &dbv, DBVT_ASCIIZ)) {
+ if (dbv.pszVal && *(dbv.pszVal))
+ szMsg = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case ID_STATUS_FREECHAT:
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(modemsg.freechat);
+ LeaveCriticalSection(&modemsg_mutex);
+ if (!szMsg && !db_get_s(NULL, "SRAway", gg_status2db(ID_STATUS_FREECHAT, "Default"), &dbv, DBVT_ASCIIZ)) {
+ if (dbv.pszVal && *(dbv.pszVal))
+ szMsg = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ case ID_STATUS_INVISIBLE:
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(modemsg.invisible);
+ LeaveCriticalSection(&modemsg_mutex);
+ if (!szMsg && !db_get_s(NULL, "SRAway", gg_status2db(ID_STATUS_INVISIBLE, "Default"), &dbv, DBVT_ASCIIZ)) {
+ if (dbv.pszVal && *(dbv.pszVal))
+ szMsg = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ default:
+ // Set last status
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(getstatusmsg(m_iStatus));
+ LeaveCriticalSection(&modemsg_mutex);
+ }
+ }
+
+ EnterCriticalSection(&sess_mutex);
+ // Check if it has message
+ if (szMsg)
+ {
+ gg_change_status_descr(sess, GG_STATUS_NOT_AVAIL_DESCR, szMsg);
+ mir_free(szMsg);
+ // Wait for disconnection acknowledge
+ }
+ else
+ {
+ gg_change_status(sess, GG_STATUS_NOT_AVAIL);
+ // Send logoff immediately
+ gg_logoff(sess);
+ }
+ LeaveCriticalSection(&sess_mutex);
+ }
+ // Else cancel connection attempt
+ else if (sock)
+ closesocket(sock);
+}
+
+////////////////////////////////////////////////////////////
+// DNS lookup function
+uint32_t gg_dnslookup(GGPROTO *gg, char *host)
+{
+ uint32_t ip;
+ struct hostent *he;
+
+ ip = inet_addr(host);
+ if (ip != INADDR_NONE)
+ {
+#ifdef DEBUGMODE
+ gg->netlog("gg_dnslookup(): Parameter \"%s\" is already IP number.", host);
+#endif
+ return ip;
+ }
+ he = gethostbyname(host);
+ if (he)
+ {
+ ip = *(uint32_t *) he->h_addr_list[0];
+#ifdef DEBUGMODE
+ gg->netlog("gg_dnslookup(): Parameter \"%s\" was resolved to %d.%d.%d.%d.", host,
+ LOBYTE(LOWORD(ip)), HIBYTE(LOWORD(ip)), LOBYTE(HIWORD(ip)), HIBYTE(HIWORD(ip)));
+#endif
+ return ip;
+ }
+ gg->netlog("gg_dnslookup(): Cannot resolve hostname \"%s\".", host);
+ return 0;
+}
+
+////////////////////////////////////////////////////////////
+// Host list decoder
+typedef struct
+{
+ char hostname[128];
+ int port;
+} GGHOST;
+#define ISHOSTALPHA(a) (((a) >= '0' && (a) <= '9') || ((a) >= 'a' && (a) <= 'z') || (a) == '.' || (a) == '-')
+int gg_decodehosts(char *var, GGHOST *hosts, int max)
+{
+ int hp = 0;
+ char *hostname = NULL;
+ char *portname = NULL;
+
+ while(var && *var && hp < max)
+ {
+ if (ISHOSTALPHA(*var))
+ {
+ hostname = var;
+
+ while(var && *var && ISHOSTALPHA(*var)) var ++;
+
+ if (var && *var == ':' && var++ && *var && isdigit(*var))
+ {
+ *(var - 1) = 0;
+ portname = var;
+ while(var && *var && isdigit(*var)) var++;
+ if (*var) { *var = 0; var ++; }
+ }
+ else
+ if (*var) { *var = 0; var ++; }
+
+ // Insert new item
+ hosts[hp].hostname[127] = 0;
+ strncpy(hosts[hp].hostname, hostname, 127);
+ hosts[hp].port = portname ? atoi(portname) : 443;
+ hp ++;
+
+ // Zero the names
+ hostname = NULL;
+ portname = NULL;
+ }
+ else
+ var ++;
+ }
+ return hp;
+}
+
+////////////////////////////////////////////////////////////
+// Main connection session thread
+void __cdecl GGPROTO::mainthread(void *)
+{
+ // Miranda variables
+ NETLIBUSERSETTINGS nlus = {0};
+ DBVARIANT dbv;
+ // Gadu-Gadu variables
+ gg_login_params p = {0};
+ gg_event *e;
+ // Host cycling variables
+ int hostnum = 0, hostcount = 0;
+ GGHOST hosts[64];
+ // Gadu-gadu login errors
+ static const struct tagReason { int type; TCHAR *str; } reason[] = {
+ { GG_FAILURE_RESOLVING, LPGENT("Miranda was unable to resolve the name of the Gadu-Gadu server to its numeric address.") },
+ { GG_FAILURE_CONNECTING, LPGENT("Miranda was unable to make a connection with a server. It is likely that the server is down, in which case you should wait for a while and try again later.") },
+ { GG_FAILURE_INVALID, LPGENT("Received invalid server response.") },
+ { GG_FAILURE_READING, LPGENT("The connection with the server was abortively closed during the connection attempt. You may have lost your local network connection.") },
+ { GG_FAILURE_WRITING, LPGENT("The connection with the server was abortively closed during the connection attempt. You may have lost your local network connection.") },
+ { GG_FAILURE_PASSWORD, LPGENT("Your Gadu-Gadu number and password combination was rejected by the Gadu-Gadu server. Please check login details at M->Options->Network->Gadu-Gadu and try again.") },
+ { GG_FAILURE_404, LPGENT("Connecting to Gadu-Gadu hub failed.") },
+ { GG_FAILURE_TLS, LPGENT("Cannot establish secure connection.") },
+ { GG_FAILURE_NEED_EMAIL, LPGENT("Server disconnected asking you for changing your e-mail.") },
+ { GG_FAILURE_INTRUDER, LPGENT("Too many login attempts with invalid password.") },
+ { GG_FAILURE_UNAVAILABLE, LPGENT("Gadu-Gadu servers are now down. Try again later.") },
+ { 0, LPGENT("Unknown") }
+ };
+ time_t logonTime = 0;
+ time_t timeDeviation = db_get_w(NULL, m_szModuleName, GG_KEY_TIMEDEVIATION, GG_KEYDEF_TIMEDEVIATION);
+ int gg_failno = 0;
+
+ netlog("gg_mainthread(%x): Server Thread Starting", this);
+#ifdef DEBUGMODE
+ gg_debug_level = GG_DEBUG_NET | GG_DEBUG_TRAFFIC | GG_DEBUG_FUNCTION | GG_DEBUG_MISC;
+#else
+ gg_debug_level = 0;
+#endif
+
+ // Broadcast that service is connecting
+ broadcastnewstatus(ID_STATUS_CONNECTING);
+
+ // Client version and misc settings
+ p.client_version = GG_DEFAULT_CLIENT_VERSION;
+ p.protocol_version = GG_DEFAULT_PROTOCOL_VERSION;
+ p.protocol_features = GG_FEATURE_DND_FFC | GG_FEATURE_UNKNOWN_100 | GG_FEATURE_USER_DATA | GG_FEATURE_MSG_ACK | GG_FEATURE_TYPING_NOTIFICATION | GG_FEATURE_MULTILOGON;
+ p.encoding = GG_ENCODING_CP1250;
+ p.status_flags = GG_STATUS_FLAG_UNKNOWN;
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_SHOWLINKS, GG_KEYDEF_SHOWLINKS))
+ p.status_flags |= GG_STATUS_FLAG_SPAM;
+
+ // Use audio
+ /* p.has_audio = 1; */
+
+ // Use async connections
+ /* p.async = 1; */
+
+ // Send Era Omnix info if set
+ p.era_omnix = db_get_b(NULL, m_szModuleName, "EraOmnix", 0);
+
+ // Setup proxy
+ nlus.cbSize = sizeof(nlus);
+ if (CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)netlib, (LPARAM)&nlus))
+ {
+ if (nlus.useProxy)
+ netlog("gg_mainthread(%x): Using proxy %s:%d.", this, nlus.szProxyServer, nlus.wProxyPort);
+ gg_proxy_enabled = nlus.useProxy;
+ gg_proxy_host = nlus.szProxyServer;
+ gg_proxy_port = nlus.wProxyPort;
+ if (nlus.useProxyAuth)
+ {
+ gg_proxy_username = nlus.szProxyAuthUser;
+ gg_proxy_password = nlus.szProxyAuthPassword;
+ }
+ else
+ gg_proxy_username = gg_proxy_password = NULL;
+ }
+ else
+ {
+ netlog("gg_mainthread(%x): Failed loading proxy settings.", this);
+ gg_proxy_enabled = 0;
+ }
+
+ // Check out manual host setting
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_MANUALHOST, GG_KEYDEF_MANUALHOST))
+ {
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_SERVERHOSTS, &dbv, DBVT_ASCIIZ))
+ {
+ hostcount = gg_decodehosts(dbv.pszVal, hosts, 64);
+ DBFreeVariant(&dbv);
+ }
+ }
+
+ // Readup password
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ))
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ p.password = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ netlog("gg_mainthread(%x): No password specified. Exiting.", this);
+ broadcastnewstatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ // Readup number
+ if (!(p.uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0)))
+ {
+ netlog("gg_mainthread(%x): No Gadu-Gadu number specified. Exiting.", this);
+ broadcastnewstatus(ID_STATUS_OFFLINE);
+ mir_free(p.password);
+ return;
+ }
+
+ // Readup SSL/TLS setting
+ if (p.tls = db_get_b(NULL, m_szModuleName, GG_KEY_SSLCONN, GG_KEYDEF_SSLCONN))
+ netlog("gg_mainthread(%x): Using TLS/SSL for connections.", this);
+
+ // Gadu-Gadu accepts image sizes upto 255
+ p.image_size = 255;
+
+ ////////////////////////////// DCC STARTUP /////////////////////////////
+ // Uin is ok so startup dcc if not started already
+ if (!dcc)
+ {
+ hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ dccstart();
+
+ // Wait for DCC
+#ifdef DEBUGMODE
+ netlog("gg_mainthread(%x): Waiting DCC service to start...", this);
+#endif
+ while (WaitForSingleObjectEx(hEvent, INFINITE, TRUE) != WAIT_OBJECT_0);
+ CloseHandle(hEvent); hEvent = NULL;
+ }
+ // Check if dcc is running and setup forwarding port
+ if (dcc && db_get_b(NULL, m_szModuleName, GG_KEY_FORWARDING, GG_KEYDEF_FORWARDING))
+ {
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_FORWARDHOST, &dbv, DBVT_ASCIIZ))
+ {
+ if (!(p.external_addr = gg_dnslookup(this, dbv.pszVal)))
+ {
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("External direct connections hostname %S is invalid. Disabling external host forwarding."), dbv.pszVal);
+ showpopup(m_tszUserName, error, GG_POPUP_WARNING | GG_POPUP_ALLOW_MSGBOX);
+ }
+ else
+ netlog("gg_mainthread(%x): Loading forwarding host %s and port %d.", dbv.pszVal, p.external_port, this);
+ if (p.external_addr) p.external_port = db_get_w(NULL, m_szModuleName, GG_KEY_FORWARDPORT, GG_KEYDEF_FORWARDPORT);
+ DBFreeVariant(&dbv);
+ }
+ }
+ // Setup client port
+ if (dcc) p.client_port = dcc->port;
+
+retry:
+ // Loadup startup status & description
+ EnterCriticalSection(&modemsg_mutex);
+ p.status_descr = mir_strdup(getstatusmsg(m_iDesiredStatus));
+ p.status = status_m2gg(m_iDesiredStatus, p.status_descr != NULL);
+
+ netlog("gg_mainthread(%x): Connecting with number %d, status %d and description \"%s\".", this, p.uin, m_iDesiredStatus,
+ p.status_descr ? p.status_descr : "<none>");
+ LeaveCriticalSection(&modemsg_mutex);
+
+ // Check manual hosts
+ if (hostnum < hostcount)
+ {
+ if (!(p.server_addr = gg_dnslookup(this, hosts[hostnum].hostname)))
+ {
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Server hostname %S is invalid. Using default hostname provided by the network."), hosts[hostnum].hostname);
+ showpopup(m_tszUserName, error, GG_POPUP_WARNING | GG_POPUP_ALLOW_MSGBOX);
+ }
+ else
+ {
+ p.server_port = hosts[hostnum].port;
+ netlog("gg_mainthread(%x): Connecting to manually specified host %s (%d.%d.%d.%d) and port %d.", this,
+ hosts[hostnum].hostname, LOBYTE(LOWORD(p.server_addr)), HIBYTE(LOWORD(p.server_addr)),
+ LOBYTE(HIWORD(p.server_addr)), HIBYTE(HIWORD(p.server_addr)), p.server_port);
+ }
+ }
+ else
+ p.server_port = p.server_addr = 0;
+
+ // Send login request
+ if (!(sess = gg_login(&p, &sock, &gg_failno)))
+ {
+ broadcastnewstatus(ID_STATUS_OFFLINE);
+ // Check if connection attempt wasn't cancelled by the user
+ if (m_iDesiredStatus != ID_STATUS_OFFLINE)
+ {
+ TCHAR error[128], *perror = NULL;
+ // Lookup for error desciption
+ if (errno == EACCES) {
+ for (int i = 0; reason[i].type; i++) if (reason[i].type == gg_failno) {
+ perror = TranslateTS(reason[i].str);
+ break;
+ }
+ }
+ if (!perror) {
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Connection cannot be established because of error:\n\t%s"), _tcserror(errno));
+ perror = error;
+ }
+ netlog("gg_mainthread(%x): %s", this, perror);
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_SHOWCERRORS, GG_KEYDEF_SHOWCERRORS))
+ showpopup(m_tszUserName, perror, GG_POPUP_ERROR | GG_POPUP_ALLOW_MSGBOX | GG_POPUP_ONCE);
+
+ // Check if we should reconnect
+ if ((gg_failno >= GG_FAILURE_RESOLVING && gg_failno != GG_FAILURE_PASSWORD && gg_failno != GG_FAILURE_INTRUDER && gg_failno != GG_FAILURE_UNAVAILABLE)
+ && errno == EACCES
+ && (db_get_b(NULL, m_szModuleName, GG_KEY_ARECONNECT, GG_KEYDEF_ARECONNECT) || (hostnum < hostcount - 1)))
+ {
+ DWORD dwInterval = db_get_b(NULL, m_szModuleName, GG_KEY_RECONNINTERVAL, GG_KEYDEF_RECONNINTERVAL), dwResult;
+ BOOL bRetry = TRUE;
+
+ hConnStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ dwResult = WaitForSingleObjectEx(hConnStopEvent, dwInterval, TRUE);
+ if ((dwResult == WAIT_OBJECT_0 && m_iDesiredStatus == ID_STATUS_OFFLINE)
+ || (dwResult == WAIT_IO_COMPLETION && Miranda_Terminated()))
+ bRetry = FALSE;
+ CloseHandle(hConnStopEvent);
+ hConnStopEvent = NULL;
+
+ // Reconnect to the next server on the list
+ if (bRetry)
+ {
+ if (hostnum < hostcount - 1) hostnum++;
+ mir_free(p.status_descr);
+ broadcastnewstatus(ID_STATUS_CONNECTING);
+ goto retry;
+ }
+ }
+ // We cannot do more about this
+ EnterCriticalSection(&modemsg_mutex);
+ m_iDesiredStatus = ID_STATUS_OFFLINE;
+ LeaveCriticalSection(&modemsg_mutex);
+ }
+ else
+ netlog("gg_mainthread(%x)): Connection attempt cancelled by the user.", this);
+ }
+ else
+ {
+ // Successfully connected
+ logonTime = time(NULL);
+ db_set_w(NULL, m_szModuleName, GG_KEY_LOGONTIME, logonTime);
+ EnterCriticalSection(&sess_mutex);
+ sess = sess;
+ LeaveCriticalSection(&sess_mutex);
+ // Subscribe users status notifications
+ notifyall();
+ // Set startup status
+ if (m_iDesiredStatus != status_gg2m(p.status))
+ refreshstatus(m_iDesiredStatus);
+ else
+ {
+ broadcastnewstatus(m_iDesiredStatus);
+ // Change status of the contact with our own UIN (if got yourself added to the contact list)
+ changecontactstatus(p.uin, p.status, p.status_descr, 0, 0, 0, 0);
+ }
+ if (check_first_conn) // First connection to the account
+ {
+ // Start search for user data
+ GetInfo(NULL, 0);
+ // Fetch user avatar
+ getUserAvatar();
+ check_first_conn = 0;
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // Main loop
+ while(isonline())
+ {
+ // Connection broken/closed
+ if (!(e = gg_watch_fd(sess)))
+ {
+ netlog("gg_mainthread(%x): Connection closed.", this);
+ EnterCriticalSection(&sess_mutex);
+ gg_free_session(sess);
+ sess = NULL;
+ LeaveCriticalSection(&sess_mutex);
+ break;
+ }
+ else
+ netlog("gg_mainthread(%x): Event: %s", this, ggdebug_eventtype(e));
+
+ switch(e->type)
+ {
+ // Client connected
+ case GG_EVENT_CONN_SUCCESS:
+ // Nada
+ break;
+
+ // Client disconnected or connection failure
+ case GG_EVENT_CONN_FAILED:
+ case GG_EVENT_DISCONNECT:
+ EnterCriticalSection(&sess_mutex);
+ gg_free_session(sess);
+ sess = NULL;
+ LeaveCriticalSection(&sess_mutex);
+ break;
+
+ // Client allowed to disconnect
+ case GG_EVENT_DISCONNECT_ACK:
+ // Send logoff
+ gg_logoff(sess);
+ break;
+
+ // Received ackowledge
+ case GG_EVENT_ACK:
+ if (e->event.ack.seq && e->event.ack.recipient)
+ {
+ ProtoBroadcastAck(m_szModuleName, getcontact((DWORD)e->event.ack.recipient, 0, 0, NULL),
+ ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) e->event.ack.seq, 0);
+ }
+ break;
+
+ // Statuslist notify (deprecated)
+ case GG_EVENT_NOTIFY:
+ case GG_EVENT_NOTIFY_DESCR:
+ {
+ struct gg_notify_reply *n;
+
+ n = (e->type == GG_EVENT_NOTIFY) ? e->event.notify : e->event.notify_descr.notify;
+
+ for (; n->uin; n++)
+ {
+ char *descr = (e->type == GG_EVENT_NOTIFY_DESCR) ? e->event.notify_descr.descr : NULL;
+ changecontactstatus(n->uin, n->status, descr, 0, n->remote_ip, n->remote_port, n->version);
+ }
+ break;
+ }
+ // Statuslist notify (version >= 6.0)
+ case GG_EVENT_NOTIFY60:
+ {
+ uin_t uin = (uin_t)db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0);
+ int i;
+ for(i = 0; e->event.notify60[i].uin; i++) {
+ if (e->event.notify60[i].uin == uin) continue;
+ changecontactstatus(e->event.notify60[i].uin, e->event.notify60[i].status, e->event.notify60[i].descr,
+ e->event.notify60[i].time, e->event.notify60[i].remote_ip, e->event.notify60[i].remote_port,
+ e->event.notify60[i].version);
+ requestAvatar(getcontact(e->event.notify60[i].uin, 0, 0, NULL), 0);
+ }
+ break;
+ }
+
+ // Pubdir search reply && read own data reply
+ case GG_EVENT_PUBDIR50_SEARCH_REPLY:
+ case GG_EVENT_PUBDIR50_READ:
+ case GG_EVENT_PUBDIR50_WRITE:
+ {
+ gg_pubdir50_t res = e->event.pubdir50;
+ int i, count;
+
+ if (e->type == GG_EVENT_PUBDIR50_SEARCH_REPLY)
+ {
+ netlog("gg_mainthread(%x): Got user info.", this);
+ // Store next search UIN
+ if (res->seq == GG_SEQ_SEARCH)
+ next_uin = gg_pubdir50_next(res);
+ }
+ else if (e->type == GG_EVENT_PUBDIR50_READ)
+ {
+ netlog("gg_mainthread(%x): Got owner info.", this);
+ }
+ else if (e->type == GG_EVENT_PUBDIR50_WRITE)
+ {
+ netlog("gg_mainthread(%x): Public directory save succesful.", this);
+ // Update user details
+ GetInfo(NULL, 0);
+ }
+
+ if ((count = gg_pubdir50_count(res)) > 0)
+ {
+ for (i = 0; i < count; i++)
+ {
+ // Loadup fields
+ const char *__fmnumber = gg_pubdir50_get(res, i, GG_PUBDIR50_UIN);
+ const char *__nick = gg_pubdir50_get(res, i, GG_PUBDIR50_NICKNAME);
+ const char *__firstname = gg_pubdir50_get(res, i, GG_PUBDIR50_FIRSTNAME);
+ const char *__lastname = gg_pubdir50_get(res, i, GG_PUBDIR50_LASTNAME);
+ const char *__familyname = gg_pubdir50_get(res, i, GG_PUBDIR50_FAMILYNAME);
+ const char *__birthyear = gg_pubdir50_get(res, i, GG_PUBDIR50_BIRTHYEAR);
+ const char *__city = gg_pubdir50_get(res, i, GG_PUBDIR50_CITY);
+ const char *__origincity = gg_pubdir50_get(res, i, GG_PUBDIR50_FAMILYCITY);
+ const char *__gender = gg_pubdir50_get(res, i, GG_PUBDIR50_GENDER);
+ const char *__status = gg_pubdir50_get(res, i, GG_PUBDIR50_STATUS);
+ uin_t uin = __fmnumber ? atoi(__fmnumber) : 0;
+
+ HANDLE hContact = (res->seq == GG_SEQ_CHINFO) ? NULL : getcontact(uin, 0, 0, NULL);
+ netlog("gg_mainthread(%x): Search result for uin %d, seq %d.", this, uin, res->seq);
+ if (res->seq == GG_SEQ_SEARCH)
+ {
+ char strFmt1[64];
+ char strFmt2[64];
+
+ mir_snprintf(strFmt2, sizeof(strFmt2), "%s", (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, status_gg2m(atoi(__status)), 0));
+ if (__city)
+ {
+ mir_snprintf(strFmt1, sizeof(strFmt1), ", %s %s", Translate("City:"), __city);
+ strncat(strFmt2, strFmt1, sizeof(strFmt2) - strlen(strFmt2));
+ }
+ if (__birthyear)
+ {
+ time_t t = time(NULL);
+ struct tm *lt = localtime(&t);
+ int br = atoi(__birthyear);
+
+ if (br < (lt->tm_year + 1900) && br > 1900)
+ {
+ mir_snprintf(strFmt1, sizeof(strFmt1), ", %s %d", Translate("Age:"), (lt->tm_year + 1900) - br);
+ strncat(strFmt2, strFmt1, sizeof(strFmt2) - strlen(strFmt2));
+ }
+ }
+
+ GGSEARCHRESULT sr;
+ memset(&sr, 0, sizeof(sr));
+ sr.cbSize = sizeof(sr);
+ sr.nick = mir_a2t(__nick);
+ sr.firstName = mir_a2t(__firstname);
+ sr.lastName = mir_a2t(__lastname);
+ sr.email = mir_a2t(strFmt2);
+ sr.id = mir_a2t(_ultoa(uin, strFmt1, 10));
+ sr.uin = uin;
+ ProtoBroadcastAck(m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) 1, (LPARAM)&sr);
+ mir_free(sr.nick);
+ mir_free(sr.firstName);
+ mir_free(sr.lastName);
+ mir_free(sr.email);
+ mir_free(sr.id);
+ }
+
+ if (((res->seq == GG_SEQ_INFO || res->seq == GG_SEQ_GETNICK) && hContact != NULL)
+ || res->seq == GG_SEQ_CHINFO)
+ {
+ // Change nickname if it's not present
+ if (__nick && (res->seq == GG_SEQ_GETNICK || res->seq == GG_SEQ_CHINFO))
+ db_set_s(hContact, m_szModuleName, GG_KEY_NICK, __nick);
+
+ if (__nick)
+ db_set_s(hContact, m_szModuleName, "NickName", __nick);
+ else if (res->seq == GG_SEQ_CHINFO)
+ db_unset(NULL, m_szModuleName, "NickName");
+
+ // Change other info
+ if (__city)
+ db_set_s(hContact, m_szModuleName, "City", __city);
+ else if (res->seq == GG_SEQ_CHINFO)
+ db_unset(NULL, m_szModuleName, "City");
+
+ if (__firstname)
+ db_set_s(hContact, m_szModuleName, "FirstName", __firstname);
+ else if (res->seq == GG_SEQ_CHINFO)
+ db_unset(NULL, m_szModuleName, "FirstName");
+
+ if (__lastname)
+ db_set_s(hContact, m_szModuleName, "LastName", __lastname);
+ else if (res->seq == GG_SEQ_CHINFO)
+ db_unset(NULL, m_szModuleName, "LastName");
+
+ if (__familyname)
+ db_set_s(hContact, m_szModuleName, "FamilyName", __familyname);
+ else if (res->seq == GG_SEQ_CHINFO)
+ db_unset(NULL, m_szModuleName, "FamilyName");
+
+ if (__origincity)
+ db_set_s(hContact, m_szModuleName, "CityOrigin", __origincity);
+ else if (res->seq == GG_SEQ_CHINFO)
+ db_unset(NULL, m_szModuleName, "CityOrigin");
+
+ if (__birthyear)
+ {
+ time_t t = time(NULL);
+ struct tm *lt = localtime(&t);
+ int br = atoi(__birthyear);
+ if (br > 0)
+ {
+ db_set_w(hContact, m_szModuleName, "Age", (WORD)(lt->tm_year + 1900 - br));
+ db_set_w(hContact, m_szModuleName, "BirthYear", (WORD)br);
+ }
+ }
+ else if (res->seq == GG_SEQ_CHINFO)
+ {
+ db_unset(NULL, m_szModuleName, "Age");
+ db_unset(NULL, m_szModuleName, "BirthYear");
+ }
+
+ // Gadu-Gadu Male <-> Female
+ if (__gender)
+ {
+ if (res->seq == GG_SEQ_CHINFO)
+ db_set_b(hContact, m_szModuleName, "Gender",
+ (BYTE)(!strcmp(__gender, GG_PUBDIR50_GENDER_SET_MALE) ? 'M' :
+ (!strcmp(__gender, GG_PUBDIR50_GENDER_SET_FEMALE) ? 'F' : '?')));
+ else
+ db_set_b(hContact, m_szModuleName, "Gender",
+ (BYTE)(!strcmp(__gender, GG_PUBDIR50_GENDER_MALE) ? 'M' :
+ (!strcmp(__gender, GG_PUBDIR50_GENDER_FEMALE) ? 'F' : '?')));
+ }
+ else if (res->seq == GG_SEQ_CHINFO)
+ {
+ db_unset(NULL, m_szModuleName, "Gender");
+ }
+
+ netlog("gg_mainthread(%x): Setting user info for uin %d.", this, uin);
+ ProtoBroadcastAck(m_szModuleName, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
+ }
+ }
+ }
+ if (res->seq == GG_SEQ_SEARCH)
+ ProtoBroadcastAck(m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
+ break;
+ }
+
+ // Status (deprecated)
+ case GG_EVENT_STATUS:
+ changecontactstatus(e->event.status.uin, e->event.status.status, e->event.status.descr, 0, 0, 0, 0);
+ break;
+
+ // Status (version >= 6.0)
+ case GG_EVENT_STATUS60:
+ {
+ HANDLE hContact = getcontact(e->event.status60.uin, 0, 0, NULL);
+ int oldstatus = db_get_w(hContact, m_szModuleName, GG_KEY_STATUS, (WORD)ID_STATUS_OFFLINE);
+ uin_t uin = (uin_t)db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0);
+
+ if (e->event.status60.uin == uin)
+ {
+ // Status was changed by the user simultaneously logged on using different Miranda account or IM client
+ int iStatus = status_gg2m(e->event.status60.status);
+ CallProtoService(m_szModuleName, PS_SETAWAYMSG, iStatus, (LPARAM)e->event.status60.descr);
+ CallProtoService(m_szModuleName, PS_SETSTATUS, iStatus, 0);
+ }
+
+ changecontactstatus(e->event.status60.uin, e->event.status60.status, e->event.status60.descr,
+ e->event.status60.time, e->event.status60.remote_ip, e->event.status60.remote_port, e->event.status60.version);
+
+ if (oldstatus == ID_STATUS_OFFLINE && db_get_w(hContact, m_szModuleName, GG_KEY_STATUS, (WORD)ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
+ requestAvatar(hContact, 0);
+ }
+ break;
+
+ // Received userlist / or put info
+ case GG_EVENT_USERLIST:
+ switch (e->event.userlist.type) {
+ case GG_USERLIST_GET_REPLY:
+ if (e->event.userlist.reply) {
+ parsecontacts(e->event.userlist.reply);
+ MessageBox(NULL, TranslateT("List import successful."), m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ }
+ break;
+
+ case GG_USERLIST_PUT_REPLY:
+ if (is_list_remove)
+ MessageBox(NULL, TranslateT("List remove successful."), m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ else
+ MessageBox(NULL, TranslateT("List export successful."), m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ break;
+ }
+ break;
+
+ // Received message
+ case GG_EVENT_MSG:
+ // This is CTCP request
+ if ((e->event.msg.msgclass & GG_CLASS_CTCP))
+ {
+ dccconnect(e->event.msg.sender);
+ }
+ // Check if not conference and block
+ else if (!e->event.msg.recipients_count || gc_enabled)
+ {
+ // Check if groupchat
+ if (e->event.msg.recipients_count && gc_enabled && !db_get_b(NULL, m_szModuleName, GG_KEY_IGNORECONF, GG_KEYDEF_IGNORECONF))
+ {
+ char *chat = gc_getchat(e->event.msg.sender, e->event.msg.recipients, e->event.msg.recipients_count);
+ if (chat)
+ {
+ char id[32];
+ GCDEST gcdest = {m_szModuleName, chat, GC_EVENT_MESSAGE};
+ GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
+ time_t t = time(NULL);
+
+ UIN2ID(e->event.msg.sender, id);
+
+ gcevent.pszUID = id;
+ gcevent.pszText = e->event.msg.message;
+ gcevent.pszNick = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) getcontact(e->event.msg.sender, 1, 0, NULL), 0);
+ gcevent.time = (!(e->event.msg.msgclass & GG_CLASS_OFFLINE) || e->event.msg.time > (t - timeDeviation)) ? t : e->event.msg.time;
+ gcevent.dwFlags = GCEF_ADDTOLOG;
+ netlog("gg_mainthread(%x): Conference message to room %s & id %s.", this, chat, id);
+ CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
+ }
+ }
+ // Check if not empty message ( who needs it? )
+ else if (!e->event.msg.recipients_count && e->event.msg.message && *e->event.msg.message && strcmp(e->event.msg.message, "\xA0\0"))
+ {
+ CCSDATA ccs = {0};
+ PROTORECVEVENT pre = {0};
+ time_t t = time(NULL);
+ ccs.szProtoService = PSR_MESSAGE;
+ ccs.hContact = getcontact(e->event.msg.sender, 1, 0, NULL);
+ ccs.lParam = (LPARAM)&pre;
+ pre.timestamp = (!(e->event.msg.msgclass & GG_CLASS_OFFLINE) || e->event.msg.time > (t - timeDeviation)) ? t : e->event.msg.time;
+ pre.szMessage = e->event.msg.message;
+ CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs);
+ }
+
+ // RichEdit format included (image)
+ if (e->event.msg.formats_length &&
+ db_get_b(NULL, m_szModuleName, GG_KEY_IMGRECEIVE, GG_KEYDEF_IMGRECEIVE) &&
+ !(db_get_b(getcontact(e->event.msg.sender, 1, 0, NULL), "Ignore", "Mask1", 0) & IGNOREEVENT_MESSAGE))
+ {
+ char *formats = (char*)e->event.msg.formats;
+ int len = 0, formats_len = e->event.msg.formats_length, add_ptr;
+
+ while (len < formats_len)
+ {
+ add_ptr = sizeof(struct gg_msg_richtext_format);
+ if (((struct gg_msg_richtext_format*)formats)->font & GG_FONT_IMAGE)
+ {
+ struct gg_msg_richtext_image *image = (struct gg_msg_richtext_image *)(formats + add_ptr);
+ EnterCriticalSection(&sess_mutex);
+ gg_image_request(sess, e->event.msg.sender, image->size, image->crc32);
+ LeaveCriticalSection(&sess_mutex);
+
+ netlog("gg_mainthread: image request sent!");
+ add_ptr += sizeof(struct gg_msg_richtext_image);
+ }
+ if (((struct gg_msg_richtext_format*)formats)->font & GG_FONT_COLOR)
+ add_ptr += sizeof(struct gg_msg_richtext_color);
+ len += add_ptr;
+ formats += add_ptr;
+ }
+ }
+ }
+ break;
+
+ // Message sent from concurrent user session
+ case GG_EVENT_MULTILOGON_MSG:
+ if (e->event.multilogon_msg.recipients_count && gc_enabled && !db_get_b(NULL, m_szModuleName, GG_KEY_IGNORECONF, GG_KEYDEF_IGNORECONF))
+ {
+ char *chat = gc_getchat(e->event.multilogon_msg.sender, e->event.multilogon_msg.recipients, e->event.multilogon_msg.recipients_count);
+ if (chat)
+ {
+ char id[32];
+ DBVARIANT dbv;
+ GCDEST gcdest = {m_szModuleName, chat, GC_EVENT_MESSAGE};
+ GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
+
+ UIN2ID(db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0), id);
+
+ gcevent.pszUID = id;
+ gcevent.pszText = e->event.multilogon_msg.message;
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_NICK, &dbv, DBVT_ASCIIZ))
+ gcevent.pszNick = dbv.pszVal;
+ else
+ gcevent.pszNick = Translate("Me");
+ gcevent.time = e->event.multilogon_msg.time;
+ gcevent.bIsMe = 1;
+ gcevent.dwFlags = GCEF_ADDTOLOG;
+ netlog("gg_mainthread(%x): Sent conference message to room %s.", this, chat);
+ CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
+ if (gcevent.pszNick == dbv.pszVal) DBFreeVariant(&dbv);
+ }
+ }
+ else if (!e->event.multilogon_msg.recipients_count && e->event.multilogon_msg.message && *e->event.multilogon_msg.message
+ && strcmp(e->event.multilogon_msg.message, "\xA0\0"))
+ {
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = m_szModuleName;
+ dbei.timestamp = (DWORD)e->event.multilogon_msg.time;
+ dbei.flags = DBEF_SENT;
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = (DWORD)strlen(e->event.multilogon_msg.message) + 1;
+ dbei.pBlob = (PBYTE)e->event.multilogon_msg.message;
+ CallService(MS_DB_EVENT_ADD, (WPARAM)getcontact(e->event.multilogon_msg.sender, 1, 0, NULL), (LPARAM)&dbei);
+ }
+ break;
+
+ // Information on active concurrent sessions
+ case GG_EVENT_MULTILOGON_INFO:
+ {
+ list_t l;
+ int* iIndexes = NULL, i;
+ netlog("gg_mainthread(): Concurrent sessions count: %d.", e->event.multilogon_info.count);
+ if (e->event.multilogon_info.count > 0)
+ iIndexes = (int*)mir_calloc(e->event.multilogon_info.count * sizeof(int));
+ EnterCriticalSection(&sessions_mutex);
+ for (l = sessions; l; l = l->next)
+ {
+ struct gg_multilogon_session* sess = (struct gg_multilogon_session*)l->data;
+ for (i = 0; i < e->event.multilogon_info.count; i++)
+ {
+ if (!memcmp(&sess->id, &e->event.multilogon_info.sessions[i].id, sizeof(gg_multilogon_id_t)) && iIndexes)
+ {
+ iIndexes[i]++;
+ break;
+ }
+ }
+ mir_free(sess->name);
+ mir_free(sess);
+ }
+ list_destroy(sessions, 0);
+ sessions = NULL;
+ for (i = 0; i < e->event.multilogon_info.count; i++)
+ {
+ gg_multilogon_session* sess = (gg_multilogon_session*)mir_alloc(sizeof(struct gg_multilogon_session));
+ memcpy(sess, &e->event.multilogon_info.sessions[i], sizeof(struct gg_multilogon_session));
+ sess->name = mir_strdup(*e->event.multilogon_info.sessions[i].name != '\0'
+ ? e->event.multilogon_info.sessions[i].name
+ : Translate("Unknown client"));
+ list_add(&sessions, sess, 0);
+ }
+ LeaveCriticalSection(&sessions_mutex);
+ sessions_updatedlg();
+ if (ServiceExists(MS_POPUP_ADDPOPUPCLASS))
+ {
+ const TCHAR* szText = time(NULL) - logonTime > 3
+ ? TranslateT("You have logged in at another location")
+ : TranslateT("You are logged in at another location");
+ for (i = 0; i < e->event.multilogon_info.count; i++)
+ {
+ TCHAR szMsg[MAX_SECONDLINE];
+ if (iIndexes && iIndexes[i])
+ continue;
+
+ mir_sntprintf(szMsg, SIZEOF(szMsg), _T("%s (%s)"), szText,
+ *e->event.multilogon_info.sessions[i].name != '\0' ?
+ _A2T(e->event.multilogon_info.sessions[i].name) : TranslateT("Unknown client"));
+ showpopup(m_tszUserName, szMsg, GG_POPUP_MULTILOGON);
+ }
+ }
+ mir_free(iIndexes);
+ }
+ break;
+
+ // Image reply sent
+ case GG_EVENT_IMAGE_REPLY:
+ // Get rid of empty image
+ if (e->event.image_reply.size && e->event.image_reply.image)
+ {
+ HANDLE hContact = getcontact(e->event.image_reply.sender, 1, 0, NULL);
+ void *img = (void *)img_loadpicture(e, 0);
+
+ if (!img)
+ break;
+
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_IMGMETHOD, GG_KEYDEF_IMGMETHOD) == 1 || img_opened(e->event.image_reply.sender))
+ {
+ img_display(hContact, img);
+ }
+ else if (db_get_b(NULL, m_szModuleName, GG_KEY_IMGMETHOD, GG_KEYDEF_IMGMETHOD) == 2)
+ {
+ img_displayasmsg(hContact, img);
+ }
+ else
+ {
+ CLISTEVENT cle = {0};
+ char service[128];
+ mir_snprintf(service, sizeof(service), GGS_RECVIMAGE, m_szModuleName);
+
+ cle.cbSize = sizeof(cle);
+ cle.hContact = hContact;
+ cle.hIcon = LoadIconEx("image", FALSE);
+ cle.flags = CLEF_URGENT;
+ cle.hDbEvent = (HANDLE)"img";
+ cle.lParam = (LPARAM)img;
+ cle.pszService = service;
+ cle.pszTooltip = Translate("Incoming image");
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle);
+ ReleaseIconEx("image", FALSE);
+ }
+ }
+ break;
+
+ // Image send request
+ case GG_EVENT_IMAGE_REQUEST:
+ img_sendonrequest(e);
+ break;
+
+ // Incoming direct connection
+ case GG_EVENT_DCC7_NEW:
+ {
+ struct gg_dcc7 *dcc7 = e->event.dcc7_new;
+ netlog("gg_mainthread(%x): Incoming direct connection.", this);
+ dcc7->contact = getcontact(dcc7->peer_uin, 0, 0, NULL);
+
+ // Check if user is on the list and if it is my uin
+ if (!dcc7->contact || db_get_b(NULL, m_szModuleName, GG_KEY_UIN, -1) != dcc7->uin) {
+ gg_dcc7_free(dcc7);
+ e->event.dcc7_new = NULL;
+ break;
+ }
+
+ // Add to waiting transfers
+ EnterCriticalSection(&ft_mutex);
+ list_add(&transfers, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
+
+ //////////////////////////////////////////////////
+ // Add file recv request
+ {
+ CCSDATA ccs;
+ PROTORECVEVENT pre;
+ char *szBlob;
+ char *szFilename = (char*)dcc7->filename;
+ char *szMsg = (char*)dcc7->filename;
+ netlog("gg_mainthread(%x): Client: %d, File ack filename \"%s\" size %d.", this, dcc7->peer_uin,
+ dcc7->filename, dcc7->size);
+ // Make new ggtransfer struct
+ szBlob = (char *)malloc(sizeof(DWORD) + strlen(szFilename) + strlen(szMsg) + 2);
+ // Store current dcc
+ *(PDWORD)szBlob = (DWORD)dcc7;
+ // Store filename
+ strcpy(szBlob + sizeof(DWORD), szFilename);
+ // Store description
+ strcpy(szBlob + sizeof(DWORD) + strlen(szFilename) + 1, szMsg);
+ ccs.szProtoService = PSR_FILE;
+ ccs.hContact = dcc7->contact;
+ ccs.wParam = 0;
+ ccs.lParam = (LPARAM)&pre;
+ pre.flags = 0;
+ pre.timestamp = time(NULL);
+ pre.szMessage = szBlob;
+ pre.lParam = 0;
+ CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs);
+ free(szBlob);
+ }
+ e->event.dcc7_new = NULL;
+ }
+ break;
+
+ // Direct connection rejected
+ case GG_EVENT_DCC7_REJECT:
+ {
+ struct gg_dcc7 *dcc7 = e->event.dcc7_reject.dcc7;
+ if (dcc7->type == GG_SESSION_DCC7_SEND)
+ {
+ netlog("gg_mainthread(%x): File transfer denied by client %d (reason = %d).", this, dcc7->peer_uin, e->event.dcc7_reject.reason);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DENIED, dcc7, 0);
+
+ // Remove from watches and free
+ EnterCriticalSection(&ft_mutex);
+ list_remove(&watches, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
+ gg_dcc7_free(dcc7);
+ }
+ else
+ {
+ netlog("gg_mainthread(%x): File transfer aborted by client %d.", this, dcc7->peer_uin);
+
+ // Remove transfer from waiting list
+ EnterCriticalSection(&ft_mutex);
+ list_remove(&transfers, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
+ }
+ }
+ break;
+
+ // Direct connection error
+ case GG_EVENT_DCC7_ERROR:
+ {
+ struct gg_dcc7 *dcc7 = e->event.dcc7_error_ex.dcc7;
+ switch (e->event.dcc7_error)
+ {
+ case GG_ERROR_DCC7_HANDSHAKE:
+ netlog("gg_mainthread(%x): Client: %d, Handshake error.", this, dcc7 ? dcc7->peer_uin : 0);
+ break;
+ case GG_ERROR_DCC7_NET:
+ netlog("gg_mainthread(%x): Client: %d, Network error.", this, dcc7 ? dcc7->peer_uin : 0);
+ break;
+ case GG_ERROR_DCC7_FILE:
+ netlog("gg_mainthread(%x): Client: %d, File read/write error.", this, dcc7 ? dcc7->peer_uin : 0);
+ break;
+ case GG_ERROR_DCC7_EOF:
+ netlog("gg_mainthread(%x): Client: %d, End of file/connection error.", this, dcc7 ? dcc7->peer_uin : 0);
+ break;
+ case GG_ERROR_DCC7_REFUSED:
+ netlog("gg_mainthread(%x): Client: %d, Connection refused error.", this, dcc7 ? dcc7->peer_uin : 0);
+ break;
+ case GG_ERROR_DCC7_RELAY:
+ netlog("gg_mainthread(%x): Client: %d, Relay connection error.", this, dcc7 ? dcc7->peer_uin : 0);
+ break;
+ default:
+ netlog("gg_mainthread(%x): Client: %d, Unknown error.", this, dcc7 ? dcc7->peer_uin : 0);
+ }
+ if (!dcc7) break;
+
+ // Remove from watches
+ list_remove(&watches, dcc7, 0);
+
+ // Close file & fail
+ if (dcc7->file_fd != -1)
+ {
+ _close(dcc7->file_fd);
+ dcc7->file_fd = -1;
+ }
+
+ if (dcc7->contact)
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
+
+ // Free dcc
+ gg_dcc7_free(dcc7);
+ }
+ break;
+
+ case GG_EVENT_XML_ACTION:
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)) {
+ HXML hXml;
+ TCHAR *xmlAction;
+ TCHAR *tag;
+
+ xmlAction = mir_a2t(e->event.xml_action.data);
+ tag = mir_a2t("events");
+ hXml = xi.parseString(xmlAction, 0, tag);
+
+ if (hXml != NULL) {
+ HXML node;
+ char *type, *sender;
+
+ mir_free(tag);
+ tag = mir_a2t("event/type");
+ node = xi.getChildByPath(hXml, tag, 0);
+ type = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
+
+ mir_free(tag);
+ tag = mir_a2t("event/sender");
+ node = xi.getChildByPath(hXml, tag, 0);
+ sender = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
+ netlog("gg_mainthread(%x): XML Action type: %s.", this, type != NULL ? type : "unknown");
+ // Avatar change notify
+ if (type != NULL && !strcmp(type, "28")) {
+ netlog("gg_mainthread(%x): Client %s changed his avatar.", this, sender);
+ requestAvatar(getcontact(atoi(sender), 0, 0, NULL), 0);
+ }
+ mir_free(type);
+ mir_free(sender);
+ xi.destroyNode(hXml);
+ }
+ mir_free(tag);
+ mir_free(xmlAction);
+ }
+ break;
+
+ case GG_EVENT_TYPING_NOTIFICATION:
+ {
+ HANDLE hContact = getcontact(e->event.typing_notification.uin, 0, 0, NULL);
+#ifdef DEBUGMODE
+ netlog("gg_mainthread(%x): Typing notification from %d (%d).", this,
+ e->event.typing_notification.uin, e->event.typing_notification.length);
+#endif
+ CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact,
+ e->event.typing_notification.length > 0 ? 7 : PROTOTYPE_CONTACTTYPING_OFF);
+ }
+ break;
+ }
+ // Free event struct
+ gg_free_event(e);
+ }
+
+ broadcastnewstatus(ID_STATUS_OFFLINE);
+ setalloffline();
+ db_set_w(NULL, m_szModuleName, GG_KEY_LOGONTIME, 0);
+
+ // If it was unwanted disconnection reconnect
+ if (m_iDesiredStatus != ID_STATUS_OFFLINE
+ && db_get_b(NULL, m_szModuleName, GG_KEY_ARECONNECT, GG_KEYDEF_ARECONNECT))
+ {
+ netlog("gg_mainthread(%x): Unintentional disconnection detected. Going to reconnect...", this);
+ hostnum = 0;
+ broadcastnewstatus(ID_STATUS_CONNECTING);
+ mir_free(p.status_descr);
+ goto retry;
+ }
+
+ mir_free(p.password);
+ mir_free(p.status_descr);
+
+ // Destroy concurrent sessions list
+ {
+ list_t l;
+ EnterCriticalSection(&sessions_mutex);
+ for (l = sessions; l; l = l->next)
+ {
+ struct gg_multilogon_session* sess = (struct gg_multilogon_session*)l->data;
+ mir_free(sess->name);
+ mir_free(sess);
+ }
+ list_destroy(sessions, 0);
+ sessions = NULL;
+ LeaveCriticalSection(&sessions_mutex);
+ }
+
+ // Stop dcc server
+ pth_dcc.dwThreadId = 0;
+#ifdef DEBUGMODE
+ netlog("gg_mainthread(%x): Waiting until DCC Server Thread finished, if needed.", this);
+#endif
+ threadwait(&pth_dcc);
+
+ netlog("gg_mainthread(%x): Server Thread Ending", this);
+ return;
+}
+
+////////////////////////////////////////////////////////////
+// Change status function
+void GGPROTO::broadcastnewstatus(int newStatus)
+{
+ int oldStatus;
+
+ EnterCriticalSection(&modemsg_mutex);
+ oldStatus = m_iStatus;
+ if (oldStatus == newStatus)
+ {
+ LeaveCriticalSection(&modemsg_mutex);
+ return;
+ }
+ m_iStatus = newStatus;
+ LeaveCriticalSection(&modemsg_mutex);
+
+ ProtoBroadcastAck(m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, newStatus);
+
+ netlog("gg_broadcastnewstatus(): Broadcast new status: %d.", newStatus);
+}
+
+////////////////////////////////////////////////////////////
+// When contact is deleted
+int GGPROTO::contactdeleted(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE) wParam;
+ uin_t uin; int type;
+ DBVARIANT dbv;
+
+ uin = (uin_t)db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0);
+ type = db_get_b(hContact, m_szModuleName, "ChatRoom", 0);
+
+ // Terminate conference if contact is deleted
+ if (type && !db_get_s(hContact, m_szModuleName, "ChatRoomID", &dbv, DBVT_ASCIIZ) && gc_enabled)
+ {
+ GCDEST gcdest = {m_szModuleName, dbv.pszVal, GC_EVENT_CONTROL};
+ GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
+ GGGC *chat = gc_lookup(dbv.pszVal);
+
+ netlog("gg_gc_event(): Terminating chat %x, id %s from contact list...", chat, dbv.pszVal);
+ if (chat)
+ {
+ // Destroy chat entry
+ free(chat->recipients);
+ list_remove(&chats, chat, 1);
+ // Terminate chat window / shouldn't cascade entry is deleted
+ CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gcevent);
+ CallServiceSync(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gcevent);
+ }
+
+ DBFreeVariant(&dbv);
+ return 0;
+ }
+
+ if (uin && isonline())
+ {
+ EnterCriticalSection(&sess_mutex);
+ gg_remove_notify_ex(sess, uin, GG_USER_NORMAL);
+ LeaveCriticalSection(&sess_mutex);
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////
+// When db settings changed
+
+int GGPROTO::dbsettingchanged(WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+ HANDLE hContact = (HANDLE) wParam;
+ char *szProto = NULL;
+
+ // Check if the contact is NULL or we are not online
+ if (!isonline())
+ return 0;
+
+ // If contact has been blocked
+ if (!strcmp(cws->szModule, m_szModuleName) && !strcmp(cws->szSetting, GG_KEY_BLOCK))
+ {
+ notifyuser(hContact, 1);
+ return 0;
+ }
+
+ // Contact is being renamed
+ if (gc_enabled && !strcmp(cws->szModule, m_szModuleName) && !strcmp(cws->szSetting, GG_KEY_NICK)
+ && cws->value.pszVal)
+ {
+ // Groupchat window contact is being renamed
+ DBVARIANT dbv;
+ int type = db_get_b(hContact, m_szModuleName, "ChatRoom", 0);
+ if (type && !db_get_s(hContact, m_szModuleName, "ChatRoomID", &dbv, DBVT_ASCIIZ))
+ {
+ // Most important... check redundancy (fucking cascading)
+ static int cascade = 0;
+ if (!cascade && dbv.pszVal)
+ {
+ GCDEST gcdest = {m_szModuleName, dbv.pszVal, GC_EVENT_CHANGESESSIONAME};
+ GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
+ gcevent.pszText = cws->value.pszVal;
+ netlog("gg_dbsettingchanged(): Conference %s was renamed to %s.", dbv.pszVal, cws->value.pszVal);
+ // Mark cascading
+ /* FIXME */ cascade = 1;
+ CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
+ /* FIXME */ cascade = 0;
+ }
+ DBFreeVariant(&dbv);
+ }
+ else
+ // Change contact name on all chats
+ gc_changenick(hContact, cws->value.pszVal);
+ }
+
+ // Contact list changes
+ if (!strcmp(cws->szModule, "CList"))
+ {
+ // If name changed... change nick
+ if (!strcmp(cws->szSetting, "MyHandle") && cws->value.type == DBVT_ASCIIZ && cws->value.pszVal)
+ db_set_s(hContact, m_szModuleName, GG_KEY_NICK, cws->value.pszVal);
+
+ // If not on list changed
+ if (!strcmp(cws->szSetting, "NotOnList"))
+ {
+ if (db_get_b(hContact, "CList", "Hidden", 0))
+ return 0;
+ // Notify user normally this time if added to the list permanently
+ if (cws->value.type == DBVT_DELETED || (cws->value.type == DBVT_BYTE && cws->value.bVal == 0))
+ notifyuser(hContact, 1);
+ }
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////
+// All users set offline
+
+void GGPROTO::setalloffline()
+{
+ netlog("gg_setalloffline(): Setting buddies offline");
+ db_set_w(NULL, m_szModuleName, GG_KEY_STATUS, ID_STATUS_OFFLINE);
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !strcmp(szProto, m_szModuleName))
+ {
+ db_set_w(hContact, m_szModuleName, GG_KEY_STATUS, ID_STATUS_OFFLINE);
+ // Clear IP and port settings
+ db_unset(hContact, m_szModuleName, GG_KEY_CLIENTIP);
+ db_unset(hContact, m_szModuleName, GG_KEY_CLIENTPORT);
+ // Delete status descr
+ db_unset(hContact, "CList", GG_KEY_STATUSDESCR);
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+#ifdef DEBUGMODE
+ netlog("gg_setalloffline(): End");
+#endif
+}
+
+////////////////////////////////////////////////////////////
+// All users set offline
+
+void GGPROTO::notifyuser(HANDLE hContact, int refresh)
+{
+ uin_t uin;
+ if (!hContact) return;
+ if (isonline() && (uin = (uin_t)db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0)))
+ {
+ // Check if user should be invisible
+ // Or be blocked ?
+ if ((db_get_w(hContact, m_szModuleName, GG_KEY_APPARENT, (WORD) ID_STATUS_ONLINE) == ID_STATUS_OFFLINE) ||
+ db_get_b(hContact, "CList", "NotOnList", 0))
+ {
+ mir_cslock l(sess_mutex);
+ if (refresh) {
+ gg_remove_notify_ex(sess, uin, GG_USER_NORMAL);
+ gg_remove_notify_ex(sess, uin, GG_USER_BLOCKED);
+ }
+
+ gg_add_notify_ex(sess, uin, GG_USER_OFFLINE);
+ }
+ else if (db_get_b(hContact, m_szModuleName, GG_KEY_BLOCK, 0))
+ {
+ mir_cslock l(sess_mutex);
+ if (refresh)
+ gg_remove_notify_ex(sess, uin, GG_USER_OFFLINE);
+
+ gg_add_notify_ex(sess, uin, GG_USER_BLOCKED);
+ }
+ else {
+ mir_cslock l(sess_mutex);
+ if (refresh)
+ gg_remove_notify_ex(sess, uin, GG_USER_BLOCKED);
+
+ gg_add_notify_ex(sess, uin, GG_USER_NORMAL);
+ }
+ }
+}
+
+void GGPROTO::notifyall()
+{
+ HANDLE hContact;
+ char *szProto;
+ int count = 0, cc = 0;
+ uin_t *uins;
+ char *types;
+
+ netlog("gg_notifyall(): Subscribing notification to all users");
+ // Readup count
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !strcmp(szProto, m_szModuleName)) count ++;
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+
+ // Readup list
+ /* FIXME: If we have nothing on the list but we omit gg_notify_ex we have problem with receiving any contacts */
+ if (count == 0)
+ {
+ if (isonline())
+ {
+ EnterCriticalSection(&sess_mutex);
+ gg_notify_ex(sess, NULL, NULL, 0);
+ LeaveCriticalSection(&sess_mutex);
+ }
+ return;
+ }
+ uins = (uin_t*)calloc(sizeof(uin_t), count);
+ types = (char*)calloc(sizeof(char), count);
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact && cc < count)
+ {
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !strcmp(szProto, m_szModuleName) && (uins[cc] = db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0)))
+ {
+ if ((db_get_w(hContact, m_szModuleName, GG_KEY_APPARENT, (WORD) ID_STATUS_ONLINE) == ID_STATUS_OFFLINE) ||
+ db_get_b(hContact, "CList", "NotOnList", 0))
+ types[cc] = GG_USER_OFFLINE;
+ else if (db_get_b(hContact, m_szModuleName, GG_KEY_BLOCK, 0))
+ types[cc] = GG_USER_BLOCKED;
+ else
+ types[cc] = GG_USER_NORMAL;
+ cc ++;
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ if (cc < count) count = cc;
+
+ // Send notification
+ if (isonline())
+ {
+ EnterCriticalSection(&sess_mutex);
+ gg_notify_ex(sess, uins, types, count);
+ LeaveCriticalSection(&sess_mutex);
+ }
+
+ // Free variables
+ free(uins); free(types);
+}
+
+////////////////////////////////////////////////////////////
+// Get contact by uin
+
+HANDLE GGPROTO::getcontact(uin_t uin, int create, int inlist, TCHAR *szNick)
+{
+ // Look for contact in DB
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !strcmp(szProto, m_szModuleName)) {
+ if ((uin_t)db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0) == uin
+ && db_get_b(hContact, m_szModuleName, "ChatRoom", 0) == 0)
+ {
+ if (inlist) {
+ db_unset(hContact, "CList", "NotOnList");
+ db_unset(hContact, "CList", "Hidden");
+ }
+ return hContact;
+ }
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ if (!create) return NULL;
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
+ if (!hContact) {
+ netlog("gg_getcontact(): Failed to create Gadu-Gadu contact %s", szNick);
+ return NULL;
+ }
+
+ if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) m_szModuleName) != 0) {
+ // For some reason we failed to register the protocol for this contact
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM) hContact, 0);
+ netlog("Failed to register GG contact %d", uin);
+ return NULL;
+ }
+
+ netlog("gg_getcontact(): Added buddy: %d", uin);
+ if (!inlist)
+ db_set_b(hContact, "CList", "NotOnList", 1);
+
+ db_set_w(hContact, m_szModuleName, GG_KEY_UIN, (DWORD) uin);
+ db_set_w(hContact, m_szModuleName, GG_KEY_STATUS, ID_STATUS_OFFLINE);
+
+ // If nick specified use it
+ if (szNick)
+ db_set_ts(hContact, m_szModuleName, GG_KEY_NICK, szNick);
+ else if (isonline()) {
+ gg_pubdir50_t req;
+
+ // Search for that nick
+ if (req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)) {
+ // Add uin and search it
+ gg_pubdir50_add(req, GG_PUBDIR50_UIN, ditoa(uin));
+ gg_pubdir50_seq_set(req, GG_SEQ_GETNICK);
+ EnterCriticalSection(&sess_mutex);
+ gg_pubdir50(sess, req);
+ LeaveCriticalSection(&sess_mutex);
+ gg_pubdir50_free(req);
+ db_set_s(hContact, m_szModuleName, GG_KEY_NICK, ditoa(uin));
+ netlog("gg_getcontact(): Search for nick on uin: %d", uin);
+ }
+ }
+
+ // Add to notify list and pull avatar for the new contact
+ if (isonline())
+ {
+ PROTO_AVATAR_INFORMATIONT pai = {0};
+
+ EnterCriticalSection(&sess_mutex);
+ gg_add_notify_ex(sess, uin, (char)(inlist ? GG_USER_NORMAL : GG_USER_OFFLINE));
+ LeaveCriticalSection(&sess_mutex);
+
+ pai.cbSize = sizeof(pai);
+ pai.hContact = hContact;
+ getavatarinfo((WPARAM)GAIF_FORCE, (LPARAM)&pai);
+
+ // Change status of the contact with our own UIN (if got yourself added to the contact list)
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0) == uin) {
+ char *szMsg;
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(getstatusmsg(m_iStatus));
+ LeaveCriticalSection(&modemsg_mutex);
+ changecontactstatus(uin, status_m2gg(m_iStatus, szMsg != NULL), szMsg, 0, 0, 0, 0);
+ mir_free(szMsg);
+ }
+ }
+
+ // TODO server side list & add buddy
+ return hContact;
+}
+
+////////////////////////////////////////////////////////////
+// Status conversion
+
+int GGPROTO::status_m2gg(int status, int descr)
+{
+ // check frends only
+ int mask = db_get_b(NULL, m_szModuleName, GG_KEY_FRIENDSONLY, GG_KEYDEF_FRIENDSONLY) ? GG_STATUS_FRIENDS_MASK : 0;
+
+ if (descr)
+ {
+ switch(status)
+ {
+ case ID_STATUS_OFFLINE: return GG_STATUS_NOT_AVAIL_DESCR | mask;
+ case ID_STATUS_ONLINE: return GG_STATUS_AVAIL_DESCR | mask;
+ case ID_STATUS_AWAY: return GG_STATUS_BUSY_DESCR | mask;
+ case ID_STATUS_DND: return GG_STATUS_DND_DESCR | mask;
+ case ID_STATUS_FREECHAT: return GG_STATUS_FFC_DESCR | mask;
+ case ID_STATUS_INVISIBLE: return GG_STATUS_INVISIBLE_DESCR | mask;
+ default: return GG_STATUS_BUSY_DESCR | mask;
+ }
+ }
+ else
+ {
+ switch(status)
+ {
+ case ID_STATUS_OFFLINE: return GG_STATUS_NOT_AVAIL | mask;
+ case ID_STATUS_ONLINE: return GG_STATUS_AVAIL | mask;
+ case ID_STATUS_AWAY: return GG_STATUS_BUSY | mask;
+ case ID_STATUS_DND: return GG_STATUS_DND | mask;
+ case ID_STATUS_FREECHAT: return GG_STATUS_FFC | mask;
+ case ID_STATUS_INVISIBLE: return GG_STATUS_INVISIBLE | mask;
+ default: return GG_STATUS_BUSY | mask;
+ }
+ }
+}
+
+int GGPROTO::status_gg2m(int status)
+{
+ // ignore additional flags
+ status = GG_S(status);
+
+ // when user has status description but is offline (show it invisible)
+ if (status == GG_STATUS_NOT_AVAIL_DESCR && db_get_b(NULL, m_szModuleName, GG_KEY_SHOWINVISIBLE, GG_KEYDEF_SHOWINVISIBLE))
+ return ID_STATUS_INVISIBLE;
+
+ // rest of cases
+ switch(status)
+ {
+ case GG_STATUS_NOT_AVAIL:
+ case GG_STATUS_NOT_AVAIL_DESCR:
+ return ID_STATUS_OFFLINE;
+
+ case GG_STATUS_AVAIL:
+ case GG_STATUS_AVAIL_DESCR:
+ return ID_STATUS_ONLINE;
+
+ case GG_STATUS_BUSY:
+ case GG_STATUS_BUSY_DESCR:
+ return ID_STATUS_AWAY;
+
+ case GG_STATUS_DND:
+ case GG_STATUS_DND_DESCR:
+ return ID_STATUS_DND;
+
+ case GG_STATUS_FFC:
+ case GG_STATUS_FFC_DESCR:
+ return ID_STATUS_FREECHAT;
+
+ case GG_STATUS_INVISIBLE:
+ case GG_STATUS_INVISIBLE_DESCR:
+ return ID_STATUS_INVISIBLE;
+
+ case GG_STATUS_BLOCKED:
+ return ID_STATUS_NA;
+
+ default:
+ return ID_STATUS_OFFLINE;
+ }
+}
+
+////////////////////////////////////////////////////////////
+// Called when contact status is changed
+
+void GGPROTO::changecontactstatus(uin_t uin, int status, const char *idescr, int time, uint32_t remote_ip, uint16_t remote_port, uint32_t version)
+{
+ HANDLE hContact = getcontact(uin, 0, 0, NULL);
+
+ // Check if contact is on list
+ if (!hContact) return;
+
+ // Write contact status
+ db_set_w(hContact, m_szModuleName, GG_KEY_STATUS, (WORD)status_gg2m(status));
+
+ // Check if there's description and if it's not empty
+ if (idescr && *idescr)
+ {
+ netlog("gg_changecontactstatus(): Saving for %d status descr \"%s\".", uin, idescr);
+ db_set_s(hContact, "CList", GG_KEY_STATUSDESCR, idescr);
+ }
+ else
+ // Remove status if there's nothing
+ db_unset(hContact, "CList", GG_KEY_STATUSDESCR);
+
+ // Store contact ip and port
+ if (remote_ip) db_set_w(hContact, m_szModuleName, GG_KEY_CLIENTIP, (DWORD) swap32(remote_ip));
+ if (remote_port) db_set_w(hContact, m_szModuleName, GG_KEY_CLIENTPORT, (WORD) remote_port);
+ if (version)
+ {
+ char sversion[48];
+ db_set_w(hContact, m_szModuleName, GG_KEY_CLIENTVERSION, (DWORD) version);
+ mir_snprintf(sversion, sizeof(sversion), "%sGadu-Gadu %s", (version & 0x00ffffff) > 0x2b ? "Nowe " : "", gg_version2string(version));
+ db_set_s(hContact, m_szModuleName, "MirVer", sversion);
+ }
+}
+
+////////////////////////////////////////////////////////////
+// Returns GG client version string from packet version
+const char *gg_version2string(int v)
+{
+ const char *pstr = "???";
+ v &= 0x00ffffff;
+ switch(v)
+ {
+ case 0x2e:
+ pstr = "8.0 build 8283"; break;
+ case 0x2d:
+ pstr = "8.0 build 4881"; break;
+ case 0x2b:
+ pstr = "< 8.0"; break;
+ case 0x2a:
+ pstr = "7.7 build 3315"; break;
+ case 0x29:
+ pstr = "7.6 build 1688"; break;
+ case 0x28:
+ pstr = "7.5 build 2201"; break;
+ case 0x27:
+ pstr = "7.0 build 22"; break;
+ case 0x26:
+ pstr = "7.0 build 20"; break;
+ case 0x25:
+ pstr = "7.0 build 1"; break;
+ case 0x24:
+ pstr = "6.1 (155) / 7.6 (1359)"; break;
+ case 0x22:
+ pstr = "6.0 build 140"; break;
+ case 0x21:
+ pstr = "6.0 build 133"; break;
+ case 0x20:
+ pstr = "6.0b"; break;
+ case 0x1e:
+ pstr = "5.7b build 121"; break;
+ case 0x1c:
+ pstr = "5.7b"; break;
+ case 0x1b:
+ pstr = "5.0.5"; break;
+ case 0x19:
+ pstr = "5.0.3"; break;
+ case 0x18:
+ pstr = "5.0.0-1"; break;
+ case 0x17:
+ pstr = "4.9.2"; break;
+ case 0x16:
+ pstr = "4.9.1"; break;
+ case 0x15:
+ pstr = "4.8.9"; break;
+ case 0x14:
+ pstr = "4.8.1-3"; break;
+ case 0x11:
+ pstr = "4.6.1-10"; break;
+ case 0x10:
+ pstr = "4.5.15-22"; break;
+ case 0x0f:
+ pstr = "4.5.12"; break;
+ case 0x0b:
+ pstr = "4.0.25-30"; break;
+ default:
+ if (v < 0x0b)
+ pstr = "< 4.0.25";
+ else if (v > 0x2e)
+ pstr = ">= 8.0";
+ break;
+ }
+ return pstr;
+}
diff --git a/protocols/Gadu-Gadu/dialogs.c b/protocols/Gadu-Gadu/dialogs.c
deleted file mode 100644
index 5582d15ffb..0000000000
--- a/protocols/Gadu-Gadu/dialogs.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Gadu-Gadu Plugin for Miranda IM
-//
-// Copyright (c) 2003-2006 Adam Strzelecki <ono+miranda@java.pl>
-//
-// 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 "gg.h"
-
-static INT_PTR CALLBACK gg_genoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-static INT_PTR CALLBACK gg_confoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-static INT_PTR CALLBACK gg_advoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-extern INT_PTR CALLBACK gg_userutildlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-
-////////////////////////////////////////////////////////////////////////////////
-// SetValue
-#define SVS_NORMAL 0
-#define SVS_GENDER 1
-#define SVS_ZEROISUNSPEC 2
-#define SVS_IP 3
-#define SVS_COUNTRY 4
-#define SVS_MONTH 5
-#define SVS_SIGNED 6
-#define SVS_TIMEZONE 7
-#define SVS_GGVERSION 9
-
-static void SetValue(HWND hwndDlg, int idCtrl, HANDLE hContact, char *szModule, char *szSetting, int special, int disableIfUndef)
-{
- DBVARIANT dbv = {0};
- char str[80], *pstr = NULL;
- int unspecified = 0;
-
- dbv.type = DBVT_DELETED;
- if (szModule == NULL) unspecified = 1;
- else unspecified = DBGetContactSettingW(hContact, szModule, szSetting, &dbv);
- if (!unspecified) {
- switch (dbv.type) {
- case DBVT_BYTE:
- if (special == SVS_GENDER) {
- if (dbv.cVal == 'M') pstr = Translate("Male");
- else if (dbv.cVal == 'F') pstr = Translate("Female");
- else unspecified = 1;
- }
- else if (special == SVS_MONTH) {
- if (dbv.bVal > 0 && dbv.bVal <= 12) {
- pstr = str;
- GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVMONTHNAME1 - 1 + dbv.bVal, str, SIZEOF(str));
- }
- else unspecified = 1;
- }
- else if (special == SVS_TIMEZONE) {
- if (dbv.cVal == -100) unspecified = 1;
- else {
- pstr = str;
- mir_snprintf(str, SIZEOF(str), dbv.cVal ? "GMT%+d:%02d" : "GMT", -dbv.cVal / 2, (dbv.cVal & 1) * 30);
- }
- }
- else {
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.bVal == 0);
- pstr = _itoa(special == SVS_SIGNED ? dbv.cVal : dbv.bVal, str, 10);
- }
- break;
- case DBVT_WORD:
- if (special == SVS_COUNTRY) {
- pstr = (char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, dbv.wVal, 0);
- unspecified = pstr == NULL;
- }
- else {
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.wVal == 0);
- pstr = _itoa(special == SVS_SIGNED ? dbv.sVal : dbv.wVal, str, 10);
- }
- break;
- case DBVT_DWORD:
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.dVal == 0);
- if (special == SVS_IP) {
- struct in_addr ia;
- ia.S_un.S_addr = htonl(dbv.dVal);
- pstr = inet_ntoa(ia);
- if (dbv.dVal == 0) unspecified = 1;
- }
- else if (special == SVS_GGVERSION)
- pstr = (char *)gg_version2string(dbv.dVal);
- else
- pstr = _itoa(special == SVS_SIGNED ? dbv.lVal : dbv.dVal, str, 10);
- break;
- case DBVT_ASCIIZ:
- unspecified = (special == SVS_ZEROISUNSPEC && dbv.pszVal[0] == '\0');
- pstr = dbv.pszVal;
- break;
- default: pstr = str; lstrcpy(str, "???"); break;
- }
- }
-
- if (disableIfUndef)
- {
- EnableWindow(GetDlgItem(hwndDlg, idCtrl), !unspecified);
- if (unspecified)
- SetDlgItemText(hwndDlg, idCtrl, Translate("<not specified>"));
- else
- SetDlgItemText(hwndDlg, idCtrl, pstr);
- }
- else
- {
- EnableWindow(GetDlgItem(hwndDlg, idCtrl), TRUE);
- if (!unspecified)
- SetDlgItemText(hwndDlg, idCtrl, pstr);
- }
- DBFreeVariant(&dbv);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Options Page : Init
-int gg_options_init(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- OPTIONSDIALOGPAGE odp = { 0 };
- odp.cbSize = sizeof(odp);
- odp.position = 1003000;
- odp.hInstance = hInstance;
- odp.pszGroup = LPGEN("Network");
- odp.pszTitle = GG_PROTONAME;
- odp.dwInitParam = (LPARAM)gg;
-
- odp.pszTab = LPGEN("General");
- odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_GG_GENERAL);
- odp.pfnDlgProc = gg_genoptsdlgproc;
- odp.flags = ODPF_BOLDGROUPS | ODPF_DONTTRANSLATE;
- Options_AddPage(wParam, &odp);
-
- odp.pszTab = LPGEN("Conference");
- odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_GG_CONFERENCE);
- odp.pfnDlgProc = gg_confoptsdlgproc;
- Options_AddPage(wParam, &odp);
-
- odp.pszTab = LPGEN("Advanced");
- odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT_GG_ADVANCED);
- odp.pfnDlgProc = gg_advoptsdlgproc;
- odp.flags |= ODPF_EXPERTONLY;
- Options_AddPage(wParam, &odp);
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Check if new user data has been filled in for specified account
-void gg_checknewuser(GGPROTO* gg, uin_t uin, const char* passwd)
-{
- char oldpasswd[128];
- DBVARIANT dbv;
- uin_t olduin = (uin_t)DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0);
-
- oldpasswd[0] = '\0';
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv))
- {
- if (dbv.pszVal) strcpy(oldpasswd, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
-
- if (uin > 0 && strlen(passwd) > 0 && (uin != olduin || strcmp(oldpasswd, passwd)))
- gg->check_first_conn = 1;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Options Page : Proc
-static void gg_optsdlgcheck(HWND hwndDlg)
-{
- char text[128];
- GetDlgItemText(hwndDlg, IDC_UIN, text, sizeof(text));
- if(strlen(text))
- {
- GetDlgItemText(hwndDlg, IDC_EMAIL, text, sizeof(text));
- if(strlen(text))
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHEMAIL), SW_SHOW);
- else
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHEMAIL), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_SHOW);
- ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_SHOW);
- ShowWindow(GetDlgItem(hwndDlg, IDC_REMOVEACCOUNT), SW_SHOW);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CREATEACCOUNT), SW_HIDE);
- }
- else
- {
- ShowWindow(GetDlgItem(hwndDlg, IDC_REMOVEACCOUNT), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHEMAIL), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CREATEACCOUNT), SW_SHOW);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////
-// Proc: General options dialog
-static INT_PTR CALLBACK gg_genoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_INITDIALOG:
- {
- DBVARIANT dbv;
- DWORD num;
- GGPROTO *gg = (GGPROTO *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
-
- TranslateDialogDefault(hwndDlg);
- if (num = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
- {
- SetDlgItemText(hwndDlg, IDC_UIN, ditoa(num));
- ShowWindow(GetDlgItem(hwndDlg, IDC_CREATEACCOUNT), SW_HIDE);
- }
- else
- {
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_REMOVEACCOUNT), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_HIDE);
- }
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv)) {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- SetDlgItemText(hwndDlg, IDC_PASSWORD, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- {
- ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_HIDE);
- }
-
- CheckDlgButton(hwndDlg, IDC_FRIENDSONLY, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_FRIENDSONLY, GG_KEYDEF_FRIENDSONLY));
- CheckDlgButton(hwndDlg, IDC_SHOWINVISIBLE, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWINVISIBLE, GG_KEYDEF_SHOWINVISIBLE));
- CheckDlgButton(hwndDlg, IDC_LEAVESTATUSMSG, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_LEAVESTATUSMSG, GG_KEYDEF_LEAVESTATUSMSG));
- if(gg->gc_enabled)
- CheckDlgButton(hwndDlg, IDC_IGNORECONF, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IGNORECONF, GG_KEYDEF_IGNORECONF));
- else
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_IGNORECONF), FALSE);
- CheckDlgButton(hwndDlg, IDC_IGNORECONF, TRUE);
- }
- CheckDlgButton(hwndDlg, IDC_IMGRECEIVE, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGRECEIVE, GG_KEYDEF_IMGRECEIVE));
- CheckDlgButton(hwndDlg, IDC_SHOWLINKS, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWLINKS, GG_KEYDEF_SHOWLINKS));
- CheckDlgButton(hwndDlg, IDC_ENABLEAVATARS, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS));
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_LEAVESTATUS), IsDlgButtonChecked(hwndDlg, IDC_LEAVESTATUSMSG));
- EnableWindow(GetDlgItem(hwndDlg, IDC_IMGMETHOD), IsDlgButtonChecked(hwndDlg, IDC_IMGRECEIVE));
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)Translate("<Last Status>")); // 0
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)Translate("Online")); // ID_STATUS_ONLINE
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)Translate("Away")); // ID_STATUS_AWAY
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)Translate("DND")); // ID_STATUS_DND
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)Translate("Free for chat")); // ID_STATUS_FREECHAT
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)Translate("Invisible")); // ID_STATUS_INVISIBLE
- switch(DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, GG_KEYDEF_LEAVESTATUS))
- {
- case ID_STATUS_ONLINE:
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 1, 0);
- break;
- case ID_STATUS_AWAY:
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 2, 0);
- break;
- case ID_STATUS_DND:
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 3, 0);
- break;
- case ID_STATUS_FREECHAT:
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 4, 0);
- break;
- case ID_STATUS_INVISIBLE:
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 5, 0);
- break;
- default:
- SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 0, 0);
- }
-
- SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_ADDSTRING, 0, (LPARAM)Translate("System tray icon"));
- SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_ADDSTRING, 0, (LPARAM)Translate("Popup window"));
- SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_ADDSTRING, 0, (LPARAM)Translate("Message with [img] BBCode"));
- SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_SETCURSEL,
- DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGMETHOD, GG_KEYDEF_IMGMETHOD), 0);
- break;
- }
- case WM_COMMAND:
- {
- if ((LOWORD(wParam) == IDC_UIN || LOWORD(wParam) == IDC_PASSWORD || LOWORD(wParam) == IDC_EMAIL)
- && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
- return 0;
- switch (LOWORD(wParam)) {
- case IDC_EMAIL:
- case IDC_UIN:
- {
- gg_optsdlgcheck(hwndDlg);
- break;
- }
- case IDC_LEAVESTATUSMSG:
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_LEAVESTATUS), IsDlgButtonChecked(hwndDlg, IDC_LEAVESTATUSMSG));
- break;
- }
- case IDC_IMGRECEIVE:
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_IMGMETHOD), IsDlgButtonChecked(hwndDlg, IDC_IMGRECEIVE));
- break;
- }
- case IDC_LOSTPASS:
- {
- char email[128];
- uin_t uin;
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- GetDlgItemText(hwndDlg, IDC_UIN, email, sizeof(email));
- uin = atoi(email);
- GetDlgItemText(hwndDlg, IDC_EMAIL, email, sizeof(email));
- if (!strlen(email))
- MessageBox(
- NULL,
- Translate("You need to specify your registration e-mail first."),
- GG_PROTONAME,
- MB_OK | MB_ICONEXCLAMATION);
- else if(MessageBox(
- NULL,
- Translate("Your password will be sent to your registration e-mail.\nDo you want to continue ?"),
- GG_PROTONAME,
- MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
- gg_remindpassword(gg, uin, email);
- return FALSE;
- }
- case IDC_CREATEACCOUNT:
- case IDC_REMOVEACCOUNT:
- if(gg_isonline((GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA)))
- {
- if(MessageBox(
- NULL,
- Translate("You should disconnect before making any permanent changes with your account.\nDo you want to disconnect now ?"),
- ((GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA))->proto.m_szModuleName,
- MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
- break;
- else
- gg_disconnect((GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
- }
- case IDC_CHPASS:
- case IDC_CHEMAIL:
- {
- // Readup data
- GGUSERUTILDLGDATA dat;
- int ret;
- char pass[128], email[128];
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- GetDlgItemText(hwndDlg, IDC_UIN, pass, sizeof(pass));
- dat.uin = atoi(pass);
- GetDlgItemText(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
- GetDlgItemText(hwndDlg, IDC_EMAIL, email, sizeof(email));
- dat.pass = pass;
- dat.email = email;
- dat.gg = gg;
- if(LOWORD(wParam) == IDC_CREATEACCOUNT)
- {
- dat.mode = GG_USERUTIL_CREATE;
- ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CREATEACCOUNT), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
- }
- else if(LOWORD(wParam) == IDC_CHPASS)
- {
- dat.mode = GG_USERUTIL_PASS;
- ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHPASS), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
- }
- else if(LOWORD(wParam) == IDC_CHEMAIL)
- {
- dat.mode = GG_USERUTIL_EMAIL;
- ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHEMAIL), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
- }
- else
- {
- dat.mode = GG_USERUTIL_REMOVE;
- ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_REMOVEACCOUNT), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
- }
-
- if(ret == IDOK)
- {
- DBVARIANT dbv;
- DWORD num;
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- // Show reload required window
- ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
-
- // Update uin
- if (num = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
- SetDlgItemText(hwndDlg, IDC_UIN, ditoa(num));
- else
- SetDlgItemText(hwndDlg, IDC_UIN, "");
-
- // Update password
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv)) {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- SetDlgItemText(hwndDlg, IDC_PASSWORD, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- SetDlgItemText(hwndDlg, IDC_PASSWORD, "");
-
- // Update e-mail
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- SetDlgItemText(hwndDlg, IDC_EMAIL, "");
-
- // Update links
- gg_optsdlgcheck(hwndDlg);
-
- // Remove details
- if(LOWORD(wParam) != IDC_CHPASS && LOWORD(wParam) != IDC_CHEMAIL)
- {
- DBDeleteContactSetting(NULL, GG_PROTO, GG_KEY_NICK);
- DBDeleteContactSetting(NULL, GG_PROTO, "NickName");
- DBDeleteContactSetting(NULL, GG_PROTO, "City");
- DBDeleteContactSetting(NULL, GG_PROTO, "FirstName");
- DBDeleteContactSetting(NULL, GG_PROTO, "LastName");
- DBDeleteContactSetting(NULL, GG_PROTO, "FamilyName");
- DBDeleteContactSetting(NULL, GG_PROTO, "CityOrigin");
- DBDeleteContactSetting(NULL, GG_PROTO, "Age");
- DBDeleteContactSetting(NULL, GG_PROTO, "BirthYear");
- DBDeleteContactSetting(NULL, GG_PROTO, "Gender");
- }
- }
- }
- break;
- }
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- }
- case WM_NOTIFY:
- {
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- int status_flags = GG_STATUS_FLAG_UNKNOWN;
- char str[128];
- uin_t uin;
-
- // Write Gadu-Gadu number & password
- GetDlgItemText(hwndDlg, IDC_UIN, str, sizeof(str));
- uin = atoi(str);
- GetDlgItemText(hwndDlg, IDC_PASSWORD, str, sizeof(str));
- CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(str), (LPARAM) str);
- gg_checknewuser(gg, uin, str);
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, uin);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, str);
-
- // Write Gadu-Gadu email
- GetDlgItemText(hwndDlg, IDC_EMAIL, str, sizeof(str));
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, str);
-
- // Write checkboxes
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_FRIENDSONLY, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FRIENDSONLY));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWINVISIBLE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWINVISIBLE));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_LEAVESTATUSMSG, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LEAVESTATUSMSG));
- if (gg->gc_enabled)
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_IGNORECONF, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORECONF));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGRECEIVE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IMGRECEIVE));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWLINKS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWLINKS));
- if (IsDlgButtonChecked(hwndDlg, IDC_SHOWLINKS))
- status_flags |= GG_STATUS_FLAG_SPAM;
- EnterCriticalSection(&gg->sess_mutex);
- gg_change_status_flags(gg->sess, status_flags);
- LeaveCriticalSection(&gg->sess_mutex);
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEAVATARS));
-
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_IMGMETHOD,
- (BYTE)SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_GETCURSEL, 0, 0));
-
- // Write leave status
- switch(SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_GETCURSEL, 0, 0))
- {
- case 1:
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, ID_STATUS_ONLINE);
- break;
- case 2:
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, ID_STATUS_AWAY);
- break;
- case 3:
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, ID_STATUS_DND);
- break;
- case 4:
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, ID_STATUS_FREECHAT);
- break;
- case 5:
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, ID_STATUS_INVISIBLE);
- break;
- default:
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_LEAVESTATUS, GG_KEYDEF_LEAVESTATUS);
- }
- break;
- }
- }
- break;
- }
- }
- return FALSE;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////
-// Proc: Conference options dialog
-static INT_PTR CALLBACK gg_confoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_INITDIALOG:
- {
- DWORD num;
- GGPROTO *gg = (GGPROTO *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
-
- TranslateDialogDefault(hwndDlg);
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_ADDSTRING, 0, (LPARAM)Translate("Allow"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_ADDSTRING, 0, (LPARAM)Translate("Ask"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_ADDSTRING, 0, (LPARAM)Translate("Ignore"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_SETCURSEL,
- DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_TOTAL, GG_KEYDEF_GC_POLICY_TOTAL), 0);
-
- if (num = DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_TOTAL, GG_KEYDEF_GC_COUNT_TOTAL))
- SetDlgItemText(hwndDlg, IDC_GC_COUNT_TOTAL, ditoa(num));
-
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_ADDSTRING, 0, (LPARAM)Translate("Allow"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_ADDSTRING, 0, (LPARAM)Translate("Ask"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_ADDSTRING, 0, (LPARAM)Translate("Ignore"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_SETCURSEL,
- DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_UNKNOWN, GG_KEYDEF_GC_POLICY_UNKNOWN), 0);
-
- if (num = DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_UNKNOWN, GG_KEYDEF_GC_COUNT_UNKNOWN))
- SetDlgItemText(hwndDlg, IDC_GC_COUNT_UNKNOWN, ditoa(num));
-
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_ADDSTRING, 0, (LPARAM)Translate("Allow"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_ADDSTRING, 0, (LPARAM)Translate("Ask"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_ADDSTRING, 0, (LPARAM)Translate("Ignore"));
- SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_SETCURSEL,
- DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_DEFAULT, GG_KEYDEF_GC_POLICY_DEFAULT), 0);
- break;
- }
- case WM_COMMAND:
- {
- if ((LOWORD(wParam) == IDC_GC_COUNT_TOTAL || LOWORD(wParam) == IDC_GC_COUNT_UNKNOWN)
- && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
- return 0;
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- }
- case WM_NOTIFY:
- {
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- char str[128];
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- // Write groupchat policy
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_TOTAL,
- (WORD)SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_GETCURSEL, 0, 0));
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_UNKNOWN,
- (WORD)SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_GETCURSEL, 0, 0));
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_DEFAULT,
- (WORD)SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_GETCURSEL, 0, 0));
-
- GetDlgItemText(hwndDlg, IDC_GC_COUNT_TOTAL, str, sizeof(str));
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_TOTAL, (WORD)atoi(str));
- GetDlgItemText(hwndDlg, IDC_GC_COUNT_UNKNOWN, str, sizeof(str));
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_UNKNOWN, (WORD)atoi(str));
-
- break;
- }
- }
- break;
- }
- }
- return FALSE;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////
-// Proc: Advanced options dialog
-static INT_PTR CALLBACK gg_advoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case WM_INITDIALOG:
- {
- DBVARIANT dbv;
- DWORD num;
- GGPROTO *gg = (GGPROTO *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
-
- TranslateDialogDefault(hwndDlg);
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_SERVERHOSTS, &dbv)) {
- SetDlgItemText(hwndDlg, IDC_HOST, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- SetDlgItemText(hwndDlg, IDC_HOST, GG_KEYDEF_SERVERHOSTS);
-
- CheckDlgButton(hwndDlg, IDC_KEEPALIVE, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_KEEPALIVE, GG_KEYDEF_KEEPALIVE));
- CheckDlgButton(hwndDlg, IDC_SHOWCERRORS, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWCERRORS, GG_KEYDEF_SHOWCERRORS));
- CheckDlgButton(hwndDlg, IDC_ARECONNECT, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ARECONNECT, GG_KEYDEF_ARECONNECT));
- CheckDlgButton(hwndDlg, IDC_MSGACK, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_MSGACK, GG_KEYDEF_MSGACK));
- CheckDlgButton(hwndDlg, IDC_MANUALHOST, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_MANUALHOST, GG_KEYDEF_MANUALHOST));
- CheckDlgButton(hwndDlg, IDC_SSLCONN, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_SSLCONN, GG_KEYDEF_SSLCONN));
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
- EnableWindow(GetDlgItem(hwndDlg, IDC_PORT), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
-
- CheckDlgButton(hwndDlg, IDC_DIRECTCONNS, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_DIRECTCONNS, GG_KEYDEF_DIRECTCONNS));
- if (num = DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_DIRECTPORT, GG_KEYDEF_DIRECTPORT))
- SetDlgItemText(hwndDlg, IDC_DIRECTPORT, ditoa(num));
- CheckDlgButton(hwndDlg, IDC_FORWARDING, DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_FORWARDING, GG_KEYDEF_FORWARDING));
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_FORWARDHOST, &dbv)) {
- SetDlgItemText(hwndDlg, IDC_FORWARDHOST, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- if (num = DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_FORWARDPORT, GG_KEYDEF_FORWARDPORT))
- SetDlgItemText(hwndDlg, IDC_FORWARDPORT, ditoa(num));
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIRECTPORT), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDING), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDPORT), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDHOST), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- break;
- }
- case WM_COMMAND:
- {
- if ((LOWORD(wParam) == IDC_DIRECTPORT || LOWORD(wParam) == IDC_FORWARDHOST || LOWORD(wParam) == IDC_FORWARDPORT)
- && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
- return 0;
- switch (LOWORD(wParam)) {
- case IDC_MANUALHOST:
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
- EnableWindow(GetDlgItem(hwndDlg, IDC_PORT), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
- ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
- break;
- }
- case IDC_DIRECTCONNS:
- case IDC_FORWARDING:
- {
- EnableWindow(GetDlgItem(hwndDlg, IDC_DIRECTPORT), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDING), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDPORT), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDHOST), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
- break;
- }
- }
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- }
- case WM_NOTIFY:
- {
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- char str[512];
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_KEEPALIVE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_SHOWCERRORS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWCERRORS));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_ARECONNECT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ARECONNECT));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_MSGACK, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MSGACK));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_MANUALHOST, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_SSLCONN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SSLCONN));
-
- // Transfer settings
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_DIRECTCONNS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
- DBWriteContactSettingByte(NULL, GG_PROTO, GG_KEY_FORWARDING, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FORWARDING));
-
- // Write custom servers
- GetDlgItemText(hwndDlg, IDC_HOST, str, sizeof(str));
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_SERVERHOSTS, str);
-
- // Write direct port
- GetDlgItemText(hwndDlg, IDC_DIRECTPORT, str, sizeof(str));
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_DIRECTPORT, (WORD)atoi(str));
- // Write forwarding host
- GetDlgItemText(hwndDlg, IDC_FORWARDHOST, str, sizeof(str));
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_FORWARDHOST, str);
- GetDlgItemText(hwndDlg, IDC_FORWARDPORT, str, sizeof(str));
- DBWriteContactSettingWord(NULL, GG_PROTO, GG_KEY_FORWARDPORT, (WORD)atoi(str));
- break;
- }
- }
- break;
- }
- }
- return FALSE;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Info Page : Data
-struct GGDETAILSDLGDATA
-{
- GGPROTO *gg;
- HANDLE hContact;
- int disableUpdate;
- int updating;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// Info Page : Proc
-static INT_PTR CALLBACK gg_detailsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- struct GGDETAILSDLGDATA *dat = (struct GGDETAILSDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch(msg)
- {
- case WM_INITDIALOG:
- {
- TranslateDialogDefault(hwndDlg);
- dat = (struct GGDETAILSDLGDATA *)mir_alloc(sizeof(struct GGDETAILSDLGDATA));
- dat->hContact=(HANDLE)lParam;
- dat->disableUpdate = FALSE;
- dat->updating = FALSE;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
- // Add genders
- if (!dat->hContact)
- {
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)_T("")); // 0
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)Translate("Female")); // 1
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)Translate("Male")); // 2
- }
- break;
- }
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->idFrom)
- {
- case 0:
- switch (((LPNMHDR)lParam)->code)
- {
- case PSN_PARAMCHANGED:
- {
- dat->gg = (GGPROTO *)((LPPSHNOTIFY)lParam)->lParam;
- break;
- }
- case PSN_INFOCHANGED:
- {
- char *szProto;
- HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
- GGPROTO *gg = dat->gg;
-
- // Show updated message
- if(dat && dat->updating)
- {
- MessageBox(
- NULL,
- Translate("Your details has been uploaded to the public directory."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
- dat->updating = FALSE;
- break;
- }
-
- if (hContact == NULL)
- szProto = GG_PROTO;
- else
- szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
- if (szProto == NULL)
- break;
-
- // Disable when updating
- if(dat) dat->disableUpdate = TRUE;
-
- SetValue(hwndDlg, IDC_UIN, hContact, szProto, GG_KEY_UIN, 0, hContact != NULL);
- SetValue(hwndDlg, IDC_REALIP, hContact, szProto, GG_KEY_CLIENTIP, SVS_IP, hContact != NULL);
- SetValue(hwndDlg, IDC_PORT, hContact, szProto, GG_KEY_CLIENTPORT, SVS_ZEROISUNSPEC, hContact != NULL);
- SetValue(hwndDlg, IDC_VERSION, hContact, szProto, GG_KEY_CLIENTVERSION, SVS_GGVERSION, hContact != NULL);
-
- SetValue(hwndDlg, IDC_FIRSTNAME, hContact, szProto, "FirstName", SVS_NORMAL, hContact != NULL);
- SetValue(hwndDlg, IDC_LASTNAME, hContact, szProto, "LastName", SVS_NORMAL, hContact != NULL);
- SetValue(hwndDlg, IDC_NICKNAME, hContact, szProto, "NickName", SVS_NORMAL, hContact != NULL);
- SetValue(hwndDlg, IDC_BIRTHYEAR, hContact, szProto, "BirthYear", SVS_ZEROISUNSPEC, hContact != NULL);
- SetValue(hwndDlg, IDC_CITY, hContact, szProto, "City", SVS_NORMAL, hContact != NULL);
- SetValue(hwndDlg, IDC_FAMILYNAME, hContact, szProto, "FamilyName", SVS_NORMAL, hContact != NULL);
- SetValue(hwndDlg, IDC_CITYORIGIN, hContact, szProto, "CityOrigin", SVS_NORMAL, hContact != NULL);
-
- if (hContact)
- {
- SetValue(hwndDlg, IDC_GENDER, hContact, szProto, "Gender", SVS_GENDER, hContact != NULL);
- SetValue(hwndDlg, IDC_STATUSDESCR, hContact, "CList", GG_KEY_STATUSDESCR, SVS_NORMAL, hContact != NULL);
- }
- else switch((char)DBGetContactSettingByte(hContact, GG_PROTO, "Gender", (BYTE)'?'))
- {
- case 'F':
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0);
- break;
- case 'M':
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0);
- break;
- default:
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0);
- }
-
- // Disable when updating
- if(dat) dat->disableUpdate = FALSE;
- break;
- }
- }
- break;
- }
- break;
- case WM_COMMAND:
- if (dat && !dat->hContact && LOWORD(wParam) == IDC_SAVE && HIWORD(wParam) == BN_CLICKED)
- {
- // Save user data
- char text[256];
- gg_pubdir50_t req;
- GGPROTO *gg = dat->gg;
-
- if (!gg_isonline(gg))
- {
- MessageBox(NULL,
- Translate("You have to be logged in before you can change your details."),
- GG_PROTONAME, MB_OK | MB_ICONSTOP
- );
- break;
- }
-
- EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), FALSE);
-
- req = gg_pubdir50_new(GG_PUBDIR50_WRITE);
-
- GetDlgItemText(hwndDlg, IDC_FIRSTNAME, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, text);
-
- GetDlgItemText(hwndDlg, IDC_LASTNAME, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, text);
-
- GetDlgItemText(hwndDlg, IDC_NICKNAME, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, text);
-
- GetDlgItemText(hwndDlg, IDC_CITY, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_CITY, text);
-
- // Gadu-Gadu Female <-> Male
- switch(SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_GETCURSEL, 0, 0))
- {
- case 1:
- gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_FEMALE);
- break;
- case 2:
- gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_MALE);
- break;
- default:
- gg_pubdir50_add(req, GG_PUBDIR50_GENDER, "");
- }
-
- GetDlgItemText(hwndDlg, IDC_BIRTHYEAR, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, text);
-
- GetDlgItemText(hwndDlg, IDC_FAMILYNAME, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FAMILYNAME, text);
-
- GetDlgItemText(hwndDlg, IDC_CITYORIGIN, text, sizeof(text));
- if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FAMILYCITY, text);
-
- // Run update
- gg_pubdir50_seq_set(req, GG_SEQ_CHINFO);
- EnterCriticalSection(&gg->sess_mutex);
- gg_pubdir50(gg->sess, req);
- LeaveCriticalSection(&gg->sess_mutex);
- dat->updating = TRUE;
-
- gg_pubdir50_free(req);
- }
-
- if(dat && !dat->hContact && !dat->disableUpdate && (HIWORD(wParam) == EN_CHANGE && (
- LOWORD(wParam) == IDC_NICKNAME || LOWORD(wParam) == IDC_FIRSTNAME || LOWORD(wParam) == IDC_LASTNAME || LOWORD(wParam) == IDC_FAMILYNAME ||
- LOWORD(wParam) == IDC_CITY || LOWORD(wParam) == IDC_CITYORIGIN || LOWORD(wParam) == IDC_BIRTHYEAR) ||
- HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_GENDER))
- EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), TRUE);
-
- switch(LOWORD(wParam))
- {
- case IDCANCEL:
- SendMessage(GetParent(hwndDlg),msg,wParam,lParam);
- break;
- }
- break;
- case WM_DESTROY:
- if(dat) mir_free(dat);
- break;
- }
- return FALSE;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Info Page : Init
-int gg_details_init(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, lParam, 0);
- if ((szProto == NULL || strcmp(szProto, GG_PROTO)) && lParam || lParam && DBGetContactSettingByte((HANDLE)lParam, GG_PROTO, "ChatRoom", 0))
- return 0;
-
- // Here goes init
- {
- OPTIONSDIALOGPAGE odp = {0};
-
- odp.cbSize = sizeof(odp);
- odp.flags = ODPF_DONTTRANSLATE;
- odp.hInstance = hInstance;
- odp.pfnDlgProc = gg_detailsdlgproc;
- odp.position = -1900000000;
- odp.pszTemplate = ((HANDLE)lParam != NULL) ? MAKEINTRESOURCE(IDD_INFO_GG) : MAKEINTRESOURCE(IDD_CHINFO_GG);
- odp.ptszTitle = GG_PROTONAME;
- odp.dwInitParam = (LPARAM)gg;
- UserInfo_AddPage(wParam, &odp);
- }
-
- // Start search for user data
- if ((HANDLE)lParam == NULL)
- gg_getinfo((PROTO_INTERFACE *)gg, NULL, 0);
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////
-// Proc: Account manager options dialog
-INT_PTR CALLBACK gg_acc_mgr_guidlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-////////////////////////////////////////////////////////////////////////////////////////////
-{
- switch (msg) {
- case WM_INITDIALOG:
- {
- DBVARIANT dbv;
- DWORD num;
- GGPROTO *gg = (GGPROTO *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
-
- TranslateDialogDefault(hwndDlg);
- if (num = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
- SetDlgItemText(hwndDlg, IDC_UIN, ditoa(num));
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv)) {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- SetDlgItemText(hwndDlg, IDC_PASSWORD, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- break;
- }
- case WM_COMMAND:
- {
- switch (LOWORD(wParam)) {
- case IDC_CREATEACCOUNT:
- {
- // Readup data
- GGUSERUTILDLGDATA dat;
- int ret;
- char pass[128], email[128];
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- GetDlgItemText(hwndDlg, IDC_UIN, pass, sizeof(pass));
- dat.uin = atoi(pass);
- GetDlgItemText(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
- GetDlgItemText(hwndDlg, IDC_EMAIL, email, sizeof(email));
- dat.pass = pass;
- dat.email = email;
- dat.gg = gg;
- dat.mode = GG_USERUTIL_CREATE;
- ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CREATEACCOUNT), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
-
- if(ret == IDOK)
- {
- DBVARIANT dbv;
- DWORD num;
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- // Show reload required window
- ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
-
- // Update uin
- if (num = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
- SetDlgItemText(hwndDlg, IDC_UIN, ditoa(num));
- else
- SetDlgItemText(hwndDlg, IDC_UIN, "");
-
- // Update password
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv)) {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- SetDlgItemText(hwndDlg, IDC_PASSWORD, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- SetDlgItemText(hwndDlg, IDC_PASSWORD, "");
-
- // Update e-mail
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, &dbv)) {
- SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- SetDlgItemText(hwndDlg, IDC_EMAIL, "");
- }
- }
-
- }
- break;
- }
- case WM_NOTIFY:
- {
- switch(((LPNMHDR)lParam)->idFrom)
- {
- case 0:
- switch (((LPNMHDR) lParam)->code) {
- case PSN_APPLY:
- {
- GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- char str[128];
- uin_t uin;
-
- // Write Gadu-Gadu number & password
- GetDlgItemText(hwndDlg, IDC_UIN, str, sizeof(str));
- uin = atoi(str);
- GetDlgItemText(hwndDlg, IDC_PASSWORD, str, sizeof(str));
- CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(str), (LPARAM) str);
- gg_checknewuser(gg, uin, str);
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, uin);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, str);
-
- // Write Gadu-Gadu email
- GetDlgItemText(hwndDlg, IDC_EMAIL, str, sizeof(str));
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, str);
- }
- }
- }
- break;
- }
- }
- return FALSE;
-}
diff --git a/protocols/Gadu-Gadu/dialogs.cpp b/protocols/Gadu-Gadu/dialogs.cpp
new file mode 100644
index 0000000000..6a626f2d55
--- /dev/null
+++ b/protocols/Gadu-Gadu/dialogs.cpp
@@ -0,0 +1,1016 @@
+////////////////////////////////////////////////////////////////////////////////
+// Gadu-Gadu Plugin for Miranda IM
+//
+// Copyright (c) 2003-2006 Adam Strzelecki <ono+miranda@java.pl>
+//
+// 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 "gg.h"
+
+static INT_PTR CALLBACK gg_genoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK gg_confoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK gg_advoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+extern INT_PTR CALLBACK gg_userutildlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+////////////////////////////////////////////////////////////////////////////////
+// SetValue
+
+#define SVS_NORMAL 0
+#define SVS_GENDER 1
+#define SVS_ZEROISUNSPEC 2
+#define SVS_IP 3
+#define SVS_COUNTRY 4
+#define SVS_MONTH 5
+#define SVS_SIGNED 6
+#define SVS_TIMEZONE 7
+#define SVS_GGVERSION 9
+
+static void SetValue(HWND hwndDlg, int idCtrl, HANDLE hContact, char *szModule, char *szSetting, int special, int disableIfUndef)
+{
+ DBVARIANT dbv = {0};
+ char str[80], *pstr = NULL;
+ int unspecified = 0;
+
+ dbv.type = DBVT_DELETED;
+ if (szModule == NULL) unspecified = 1;
+ else unspecified = DBGetContactSettingW(hContact, szModule, szSetting, &dbv);
+ if (!unspecified) {
+ switch (dbv.type) {
+ case DBVT_BYTE:
+ if (special == SVS_GENDER) {
+ if (dbv.cVal == 'M') pstr = Translate("Male");
+ else if (dbv.cVal == 'F') pstr = Translate("Female");
+ else unspecified = 1;
+ }
+ else if (special == SVS_MONTH) {
+ if (dbv.bVal > 0 && dbv.bVal <= 12) {
+ pstr = str;
+ GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SABBREVMONTHNAME1 - 1 + dbv.bVal, str, SIZEOF(str));
+ }
+ else unspecified = 1;
+ }
+ else if (special == SVS_TIMEZONE) {
+ if (dbv.cVal == -100) unspecified = 1;
+ else {
+ pstr = str;
+ mir_snprintf(str, SIZEOF(str), dbv.cVal ? "GMT%+d:%02d" : "GMT", -dbv.cVal / 2, (dbv.cVal & 1) * 30);
+ }
+ }
+ else {
+ unspecified = (special == SVS_ZEROISUNSPEC && dbv.bVal == 0);
+ pstr = _itoa(special == SVS_SIGNED ? dbv.cVal : dbv.bVal, str, 10);
+ }
+ break;
+ case DBVT_WORD:
+ if (special == SVS_COUNTRY) {
+ pstr = (char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, dbv.wVal, 0);
+ unspecified = pstr == NULL;
+ }
+ else {
+ unspecified = (special == SVS_ZEROISUNSPEC && dbv.wVal == 0);
+ pstr = _itoa(special == SVS_SIGNED ? dbv.sVal : dbv.wVal, str, 10);
+ }
+ break;
+ case DBVT_DWORD:
+ unspecified = (special == SVS_ZEROISUNSPEC && dbv.dVal == 0);
+ if (special == SVS_IP) {
+ struct in_addr ia;
+ ia.S_un.S_addr = htonl(dbv.dVal);
+ pstr = inet_ntoa(ia);
+ if (dbv.dVal == 0) unspecified = 1;
+ }
+ else if (special == SVS_GGVERSION)
+ pstr = (char *)gg_version2string(dbv.dVal);
+ else
+ pstr = _itoa(special == SVS_SIGNED ? dbv.lVal : dbv.dVal, str, 10);
+ break;
+ case DBVT_ASCIIZ:
+ unspecified = (special == SVS_ZEROISUNSPEC && dbv.pszVal[0] == '\0');
+ pstr = dbv.pszVal;
+ break;
+ default: pstr = str; lstrcpyA(str, "???"); break;
+ }
+ }
+
+ if (disableIfUndef) {
+ EnableWindow(GetDlgItem(hwndDlg, idCtrl), !unspecified);
+ if (unspecified)
+ SetDlgItemText(hwndDlg, idCtrl, TranslateT("<not specified>"));
+ else
+ SetDlgItemTextA(hwndDlg, idCtrl, pstr);
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, idCtrl), TRUE);
+ if (!unspecified)
+ SetDlgItemTextA(hwndDlg, idCtrl, pstr);
+ }
+ DBFreeVariant(&dbv);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Options Page : Init
+
+int GGPROTO::options_init(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.flags = ODPF_TCHAR;
+ odp.position = 1003000;
+ odp.hInstance = hInstance;
+ odp.ptszGroup = LPGENT("Network");
+ odp.ptszTitle = m_tszUserName;
+ odp.dwInitParam = (LPARAM)this;
+
+ odp.ptszTab = LPGENT("General");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GG_GENERAL);
+ odp.pfnDlgProc = gg_genoptsdlgproc;
+ odp.flags = ODPF_TCHAR | ODPF_BOLDGROUPS | ODPF_DONTTRANSLATE;
+ Options_AddPage(wParam, &odp);
+
+ odp.ptszTab = LPGENT("Conference");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GG_CONFERENCE);
+ odp.pfnDlgProc = gg_confoptsdlgproc;
+ Options_AddPage(wParam, &odp);
+
+ odp.ptszTab = LPGENT("Advanced");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GG_ADVANCED);
+ odp.pfnDlgProc = gg_advoptsdlgproc;
+ odp.flags |= ODPF_EXPERTONLY;
+ Options_AddPage(wParam, &odp);
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Check if new user data has been filled in for specified account
+void GGPROTO::checknewuser(uin_t uin, const char* passwd)
+{
+ char oldpasswd[128];
+ DBVARIANT dbv;
+ uin_t olduin = (uin_t)db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0);
+
+ oldpasswd[0] = '\0';
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ))
+ {
+ if (dbv.pszVal) strcpy(oldpasswd, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ if (uin > 0 && strlen(passwd) > 0 && (uin != olduin || strcmp(oldpasswd, passwd)))
+ check_first_conn = 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Options Page : Proc
+
+static void gg_optsdlgcheck(HWND hwndDlg)
+{
+ TCHAR text[128];
+ GetDlgItemText(hwndDlg, IDC_UIN, text, SIZEOF(text));
+ if (text[0]) {
+ GetDlgItemText(hwndDlg, IDC_EMAIL, text, SIZEOF(text));
+ if (text[0])
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHEMAIL), SW_SHOW);
+ else
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHEMAIL), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_REMOVEACCOUNT), SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CREATEACCOUNT), SW_HIDE);
+ }
+ else {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_REMOVEACCOUNT), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHEMAIL), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CREATEACCOUNT), SW_SHOW);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Proc: General options dialog
+static INT_PTR CALLBACK gg_genoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ DWORD num;
+ GGPROTO *gg = (GGPROTO *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
+
+ TranslateDialogDefault(hwndDlg);
+ if (num = db_get_b(NULL, gg->m_szModuleName, GG_KEY_UIN, 0))
+ {
+ SetDlgItemTextA(hwndDlg, IDC_UIN, ditoa(num));
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CREATEACCOUNT), SW_HIDE);
+ }
+ else
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_REMOVEACCOUNT), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_HIDE);
+ }
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ)) {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, &dbv, DBVT_ASCIIZ)) {
+ SetDlgItemTextA(hwndDlg, IDC_EMAIL, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_LOSTPASS), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CHPASS), SW_HIDE);
+ }
+
+ CheckDlgButton(hwndDlg, IDC_FRIENDSONLY, db_get_b(NULL, gg->m_szModuleName, GG_KEY_FRIENDSONLY, GG_KEYDEF_FRIENDSONLY));
+ CheckDlgButton(hwndDlg, IDC_SHOWINVISIBLE, db_get_b(NULL, gg->m_szModuleName, GG_KEY_SHOWINVISIBLE, GG_KEYDEF_SHOWINVISIBLE));
+ CheckDlgButton(hwndDlg, IDC_LEAVESTATUSMSG, db_get_b(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUSMSG, GG_KEYDEF_LEAVESTATUSMSG));
+ if (gg->gc_enabled)
+ CheckDlgButton(hwndDlg, IDC_IGNORECONF, db_get_b(NULL, gg->m_szModuleName, GG_KEY_IGNORECONF, GG_KEYDEF_IGNORECONF));
+ else
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IGNORECONF), FALSE);
+ CheckDlgButton(hwndDlg, IDC_IGNORECONF, TRUE);
+ }
+ CheckDlgButton(hwndDlg, IDC_IMGRECEIVE, db_get_b(NULL, gg->m_szModuleName, GG_KEY_IMGRECEIVE, GG_KEYDEF_IMGRECEIVE));
+ CheckDlgButton(hwndDlg, IDC_SHOWLINKS, db_get_b(NULL, gg->m_szModuleName, GG_KEY_SHOWLINKS, GG_KEYDEF_SHOWLINKS));
+ CheckDlgButton(hwndDlg, IDC_ENABLEAVATARS, db_get_b(NULL, gg->m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LEAVESTATUS), IsDlgButtonChecked(hwndDlg, IDC_LEAVESTATUSMSG));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IMGMETHOD), IsDlgButtonChecked(hwndDlg, IDC_IMGRECEIVE));
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)TranslateT("<Last Status>")); // 0
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Online")); // ID_STATUS_ONLINE
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Away")); // ID_STATUS_AWAY
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)TranslateT("DND")); // ID_STATUS_DND
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Free for chat")); // ID_STATUS_FREECHAT
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Invisible")); // ID_STATUS_INVISIBLE
+ switch(db_get_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, GG_KEYDEF_LEAVESTATUS)) {
+ case ID_STATUS_ONLINE:
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 1, 0);
+ break;
+ case ID_STATUS_AWAY:
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 2, 0);
+ break;
+ case ID_STATUS_DND:
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 3, 0);
+ break;
+ case ID_STATUS_FREECHAT:
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 4, 0);
+ break;
+ case ID_STATUS_INVISIBLE:
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 5, 0);
+ break;
+ default:
+ SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_SETCURSEL, 0, 0);
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_ADDSTRING, 0, (LPARAM)TranslateT("System tray icon"));
+ SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_ADDSTRING, 0, (LPARAM)TranslateT("Popup window"));
+ SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_ADDSTRING, 0, (LPARAM)TranslateT("Message with [img] BBCode"));
+ SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_SETCURSEL,
+ db_get_b(NULL, gg->m_szModuleName, GG_KEY_IMGMETHOD, GG_KEYDEF_IMGMETHOD), 0);
+ break;
+ }
+ case WM_COMMAND:
+ {
+ if ((LOWORD(wParam) == IDC_UIN || LOWORD(wParam) == IDC_PASSWORD || LOWORD(wParam) == IDC_EMAIL)
+ && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+
+ switch (LOWORD(wParam)) {
+ case IDC_EMAIL:
+ case IDC_UIN:
+ gg_optsdlgcheck(hwndDlg);
+ break;
+
+ case IDC_LEAVESTATUSMSG:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LEAVESTATUS), IsDlgButtonChecked(hwndDlg, IDC_LEAVESTATUSMSG));
+ break;
+
+ case IDC_IMGRECEIVE:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IMGMETHOD), IsDlgButtonChecked(hwndDlg, IDC_IMGRECEIVE));
+ break;
+
+ case IDC_LOSTPASS:
+ {
+ char email[128];
+ uin_t uin;
+ GetDlgItemTextA(hwndDlg, IDC_UIN, email, sizeof(email));
+ uin = atoi(email);
+ GetDlgItemTextA(hwndDlg, IDC_EMAIL, email, sizeof(email));
+ if (!strlen(email))
+ MessageBox(NULL, TranslateT("You need to specify your registration e-mail first."),
+ gg->m_tszUserName, MB_OK | MB_ICONEXCLAMATION);
+ else if (MessageBox(NULL,
+ TranslateT("Your password will be sent to your registration e-mail.\nDo you want to continue ?"),
+ gg->m_tszUserName,
+ MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
+ gg->remindpassword(uin, email);
+ return FALSE;
+ }
+ case IDC_CREATEACCOUNT:
+ case IDC_REMOVEACCOUNT:
+ if (gg->isonline())
+ {
+ if (MessageBox(
+ NULL,
+ TranslateT("You should disconnect before making any permanent changes with your account.\nDo you want to disconnect now ?"),
+ gg->m_tszUserName,
+ MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
+ break;
+ else
+ gg->disconnect();
+ }
+ case IDC_CHPASS:
+ case IDC_CHEMAIL:
+ {
+ // Readup data
+ GGUSERUTILDLGDATA dat;
+ int ret;
+ char pass[128], email[128];
+ GetDlgItemTextA(hwndDlg, IDC_UIN, pass, sizeof(pass));
+ dat.uin = atoi(pass);
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
+ GetDlgItemTextA(hwndDlg, IDC_EMAIL, email, sizeof(email));
+ dat.pass = pass;
+ dat.email = email;
+ dat.gg = gg;
+ if (LOWORD(wParam) == IDC_CREATEACCOUNT)
+ {
+ dat.mode = GG_USERUTIL_CREATE;
+ ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CREATEACCOUNT), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
+ }
+ else if (LOWORD(wParam) == IDC_CHPASS)
+ {
+ dat.mode = GG_USERUTIL_PASS;
+ ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHPASS), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
+ }
+ else if (LOWORD(wParam) == IDC_CHEMAIL)
+ {
+ dat.mode = GG_USERUTIL_EMAIL;
+ ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHEMAIL), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
+ }
+ else
+ {
+ dat.mode = GG_USERUTIL_REMOVE;
+ ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_REMOVEACCOUNT), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
+ }
+
+ if (ret == IDOK)
+ {
+ DBVARIANT dbv;
+ DWORD num;
+ // Show reload required window
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
+
+ // Update uin
+ if (num = db_get_b(NULL, gg->m_szModuleName, GG_KEY_UIN, 0))
+ SetDlgItemTextA(hwndDlg, IDC_UIN, ditoa(num));
+ else
+ SetDlgItemTextA(hwndDlg, IDC_UIN, "");
+
+ // Update password
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ)) {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else SetDlgItemTextA(hwndDlg, IDC_PASSWORD, "");
+
+ // Update e-mail
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, &dbv, DBVT_ASCIIZ)) {
+ SetDlgItemTextA(hwndDlg, IDC_EMAIL, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else SetDlgItemTextA(hwndDlg, IDC_EMAIL, "");
+
+ // Update links
+ gg_optsdlgcheck(hwndDlg);
+
+ // Remove details
+ if (LOWORD(wParam) != IDC_CHPASS && LOWORD(wParam) != IDC_CHEMAIL)
+ {
+ db_unset(NULL, gg->m_szModuleName, GG_KEY_NICK);
+ db_unset(NULL, gg->m_szModuleName, "NickName");
+ db_unset(NULL, gg->m_szModuleName, "City");
+ db_unset(NULL, gg->m_szModuleName, "FirstName");
+ db_unset(NULL, gg->m_szModuleName, "LastName");
+ db_unset(NULL, gg->m_szModuleName, "FamilyName");
+ db_unset(NULL, gg->m_szModuleName, "CityOrigin");
+ db_unset(NULL, gg->m_szModuleName, "Age");
+ db_unset(NULL, gg->m_szModuleName, "BirthYear");
+ db_unset(NULL, gg->m_szModuleName, "Gender");
+ }
+ }
+ }
+ break;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ int status_flags = GG_STATUS_FLAG_UNKNOWN;
+ char str[128];
+ uin_t uin;
+
+ // Write Gadu-Gadu number & password
+ GetDlgItemTextA(hwndDlg, IDC_UIN, str, sizeof(str));
+ uin = atoi(str);
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, str, sizeof(str));
+ CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(str), (LPARAM) str);
+ gg->checknewuser(uin, str);
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_UIN, uin);
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, str);
+
+ // Write Gadu-Gadu email
+ GetDlgItemTextA(hwndDlg, IDC_EMAIL, str, sizeof(str));
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, str);
+
+ // Write checkboxes
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_FRIENDSONLY, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FRIENDSONLY));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_SHOWINVISIBLE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWINVISIBLE));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUSMSG, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LEAVESTATUSMSG));
+ if (gg->gc_enabled)
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_IGNORECONF, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORECONF));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_IMGRECEIVE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IMGRECEIVE));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_SHOWLINKS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWLINKS));
+ if (IsDlgButtonChecked(hwndDlg, IDC_SHOWLINKS))
+ status_flags |= GG_STATUS_FLAG_SPAM;
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_change_status_flags(gg->sess, status_flags);
+ LeaveCriticalSection(&gg->sess_mutex);
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_ENABLEAVATARS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEAVATARS));
+
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_IMGMETHOD,
+ (BYTE)SendDlgItemMessage(hwndDlg, IDC_IMGMETHOD, CB_GETCURSEL, 0, 0));
+
+ // Write leave status
+ switch(SendDlgItemMessage(hwndDlg, IDC_LEAVESTATUS, CB_GETCURSEL, 0, 0))
+ {
+ case 1:
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, ID_STATUS_ONLINE);
+ break;
+ case 2:
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, ID_STATUS_AWAY);
+ break;
+ case 3:
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, ID_STATUS_DND);
+ break;
+ case 4:
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, ID_STATUS_FREECHAT);
+ break;
+ case 5:
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, ID_STATUS_INVISIBLE);
+ break;
+ default:
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_LEAVESTATUS, GG_KEYDEF_LEAVESTATUS);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Proc: Conference options dialog
+
+static INT_PTR CALLBACK gg_confoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DWORD num;
+ GGPROTO *gg = (GGPROTO *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
+
+ TranslateDialogDefault(hwndDlg);
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_ADDSTRING, 0, (LPARAM)TranslateT("Allow"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ask"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_SETCURSEL,
+ db_get_w(NULL, gg->m_szModuleName, GG_KEY_GC_POLICY_TOTAL, GG_KEYDEF_GC_POLICY_TOTAL), 0);
+
+ if (num = db_get_w(NULL, gg->m_szModuleName, GG_KEY_GC_COUNT_TOTAL, GG_KEYDEF_GC_COUNT_TOTAL))
+ SetDlgItemTextA(hwndDlg, IDC_GC_COUNT_TOTAL, ditoa(num));
+
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_ADDSTRING, 0, (LPARAM)TranslateT("Allow"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ask"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_SETCURSEL,
+ db_get_w(NULL, gg->m_szModuleName, GG_KEY_GC_POLICY_UNKNOWN, GG_KEYDEF_GC_POLICY_UNKNOWN), 0);
+
+ if (num = db_get_w(NULL, gg->m_szModuleName, GG_KEY_GC_COUNT_UNKNOWN, GG_KEYDEF_GC_COUNT_UNKNOWN))
+ SetDlgItemTextA(hwndDlg, IDC_GC_COUNT_UNKNOWN, ditoa(num));
+
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_ADDSTRING, 0, (LPARAM)TranslateT("Allow"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ask"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore"));
+ SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_SETCURSEL,
+ db_get_w(NULL, gg->m_szModuleName, GG_KEY_GC_POLICY_DEFAULT, GG_KEYDEF_GC_POLICY_DEFAULT), 0);
+ break;
+ }
+ case WM_COMMAND:
+ {
+ if ((LOWORD(wParam) == IDC_GC_COUNT_TOTAL || LOWORD(wParam) == IDC_GC_COUNT_UNKNOWN)
+ && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ char str[128];
+
+ // Write groupchat policy
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_GC_POLICY_TOTAL,
+ (WORD)SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_TOTAL, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_GC_POLICY_UNKNOWN,
+ (WORD)SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_UNKNOWN, CB_GETCURSEL, 0, 0));
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_GC_POLICY_DEFAULT,
+ (WORD)SendDlgItemMessage(hwndDlg, IDC_GC_POLICY_DEFAULT, CB_GETCURSEL, 0, 0));
+
+ GetDlgItemTextA(hwndDlg, IDC_GC_COUNT_TOTAL, str, sizeof(str));
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_GC_COUNT_TOTAL, (WORD)atoi(str));
+ GetDlgItemTextA(hwndDlg, IDC_GC_COUNT_UNKNOWN, str, sizeof(str));
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_GC_COUNT_UNKNOWN, (WORD)atoi(str));
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Proc: Advanced options dialog
+static INT_PTR CALLBACK gg_advoptsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ DWORD num;
+ GGPROTO *gg = (GGPROTO *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
+
+ TranslateDialogDefault(hwndDlg);
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_SERVERHOSTS, &dbv, DBVT_ASCIIZ)) {
+ SetDlgItemTextA(hwndDlg, IDC_HOST, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else SetDlgItemTextA(hwndDlg, IDC_HOST, GG_KEYDEF_SERVERHOSTS);
+
+ CheckDlgButton(hwndDlg, IDC_KEEPALIVE, db_get_b(NULL, gg->m_szModuleName, GG_KEY_KEEPALIVE, GG_KEYDEF_KEEPALIVE));
+ CheckDlgButton(hwndDlg, IDC_SHOWCERRORS, db_get_b(NULL, gg->m_szModuleName, GG_KEY_SHOWCERRORS, GG_KEYDEF_SHOWCERRORS));
+ CheckDlgButton(hwndDlg, IDC_ARECONNECT, db_get_b(NULL, gg->m_szModuleName, GG_KEY_ARECONNECT, GG_KEYDEF_ARECONNECT));
+ CheckDlgButton(hwndDlg, IDC_MSGACK, db_get_b(NULL, gg->m_szModuleName, GG_KEY_MSGACK, GG_KEYDEF_MSGACK));
+ CheckDlgButton(hwndDlg, IDC_MANUALHOST, db_get_b(NULL, gg->m_szModuleName, GG_KEY_MANUALHOST, GG_KEYDEF_MANUALHOST));
+ CheckDlgButton(hwndDlg, IDC_SSLCONN, db_get_b(NULL, gg->m_szModuleName, GG_KEY_SSLCONN, GG_KEYDEF_SSLCONN));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PORT), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
+
+ CheckDlgButton(hwndDlg, IDC_DIRECTCONNS, db_get_b(NULL, gg->m_szModuleName, GG_KEY_DIRECTCONNS, GG_KEYDEF_DIRECTCONNS));
+ if (num = db_get_w(NULL, gg->m_szModuleName, GG_KEY_DIRECTPORT, GG_KEYDEF_DIRECTPORT))
+ SetDlgItemTextA(hwndDlg, IDC_DIRECTPORT, ditoa(num));
+ CheckDlgButton(hwndDlg, IDC_FORWARDING, db_get_b(NULL, gg->m_szModuleName, GG_KEY_FORWARDING, GG_KEYDEF_FORWARDING));
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_FORWARDHOST, &dbv, DBVT_ASCIIZ)) {
+ SetDlgItemTextA(hwndDlg, IDC_FORWARDHOST, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (num = db_get_w(NULL, gg->m_szModuleName, GG_KEY_FORWARDPORT, GG_KEYDEF_FORWARDPORT))
+ SetDlgItemTextA(hwndDlg, IDC_FORWARDPORT, ditoa(num));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DIRECTPORT), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDING), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDPORT), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDHOST), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ break;
+ }
+ case WM_COMMAND:
+ {
+ if ((LOWORD(wParam) == IDC_DIRECTPORT || LOWORD(wParam) == IDC_FORWARDHOST || LOWORD(wParam) == IDC_FORWARDPORT)
+ && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ switch (LOWORD(wParam)) {
+ case IDC_MANUALHOST:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PORT), IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
+ break;
+ }
+ case IDC_DIRECTCONNS:
+ case IDC_FORWARDING:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DIRECTPORT), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDING), IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDPORT), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FORWARDHOST), IsDlgButtonChecked(hwndDlg, IDC_FORWARDING) && IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
+ break;
+ }
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ char str[512];
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_KEEPALIVE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_SHOWCERRORS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWCERRORS));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_ARECONNECT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ARECONNECT));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_MSGACK, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MSGACK));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_MANUALHOST, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MANUALHOST));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_SSLCONN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SSLCONN));
+
+ // Transfer settings
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_DIRECTCONNS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DIRECTCONNS));
+ db_set_b(NULL, gg->m_szModuleName, GG_KEY_FORWARDING, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FORWARDING));
+
+ // Write custom servers
+ GetDlgItemTextA(hwndDlg, IDC_HOST, str, sizeof(str));
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_SERVERHOSTS, str);
+
+ // Write direct port
+ GetDlgItemTextA(hwndDlg, IDC_DIRECTPORT, str, sizeof(str));
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_DIRECTPORT, (WORD)atoi(str));
+ // Write forwarding host
+ GetDlgItemTextA(hwndDlg, IDC_FORWARDHOST, str, sizeof(str));
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_FORWARDHOST, str);
+ GetDlgItemTextA(hwndDlg, IDC_FORWARDPORT, str, sizeof(str));
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_FORWARDPORT, (WORD)atoi(str));
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Info Page : Data
+struct GGDETAILSDLGDATA
+{
+ GGPROTO *gg;
+ HANDLE hContact;
+ int disableUpdate;
+ int updating;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Info Page : Proc
+static INT_PTR CALLBACK gg_detailsdlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct GGDETAILSDLGDATA *dat = (struct GGDETAILSDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ dat = (struct GGDETAILSDLGDATA *)mir_alloc(sizeof(struct GGDETAILSDLGDATA));
+ dat->hContact=(HANDLE)lParam;
+ dat->disableUpdate = FALSE;
+ dat->updating = FALSE;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+ // Add genders
+ if (!dat->hContact)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)_T("")); // 0
+ SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)TranslateT("Female")); // 1
+ SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)TranslateT("Male")); // 2
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch (((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_PARAMCHANGED:
+ dat->gg = (GGPROTO *)((LPPSHNOTIFY)lParam)->lParam;
+ break;
+
+ case PSN_INFOCHANGED:
+ {
+ char *szProto;
+ HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
+ GGPROTO *gg = dat->gg;
+
+ // Show updated message
+ if (dat && dat->updating)
+ {
+ MessageBox(NULL, TranslateT("Your details has been uploaded to the public directory."),
+ gg->m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ dat->updating = FALSE;
+ break;
+ }
+
+ if (hContact == NULL)
+ szProto = gg->m_szModuleName;
+ else
+ szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto == NULL)
+ break;
+
+ // Disable when updating
+ if (dat) dat->disableUpdate = TRUE;
+
+ SetValue(hwndDlg, IDC_UIN, hContact, szProto, GG_KEY_UIN, 0, hContact != NULL);
+ SetValue(hwndDlg, IDC_REALIP, hContact, szProto, GG_KEY_CLIENTIP, SVS_IP, hContact != NULL);
+ SetValue(hwndDlg, IDC_PORT, hContact, szProto, GG_KEY_CLIENTPORT, SVS_ZEROISUNSPEC, hContact != NULL);
+ SetValue(hwndDlg, IDC_VERSION, hContact, szProto, GG_KEY_CLIENTVERSION, SVS_GGVERSION, hContact != NULL);
+
+ SetValue(hwndDlg, IDC_FIRSTNAME, hContact, szProto, "FirstName", SVS_NORMAL, hContact != NULL);
+ SetValue(hwndDlg, IDC_LASTNAME, hContact, szProto, "LastName", SVS_NORMAL, hContact != NULL);
+ SetValue(hwndDlg, IDC_NICKNAME, hContact, szProto, "NickName", SVS_NORMAL, hContact != NULL);
+ SetValue(hwndDlg, IDC_BIRTHYEAR, hContact, szProto, "BirthYear", SVS_ZEROISUNSPEC, hContact != NULL);
+ SetValue(hwndDlg, IDC_CITY, hContact, szProto, "City", SVS_NORMAL, hContact != NULL);
+ SetValue(hwndDlg, IDC_FAMILYNAME, hContact, szProto, "FamilyName", SVS_NORMAL, hContact != NULL);
+ SetValue(hwndDlg, IDC_CITYORIGIN, hContact, szProto, "CityOrigin", SVS_NORMAL, hContact != NULL);
+
+ if (hContact)
+ {
+ SetValue(hwndDlg, IDC_GENDER, hContact, szProto, "Gender", SVS_GENDER, hContact != NULL);
+ SetValue(hwndDlg, IDC_STATUSDESCR, hContact, "CList", GG_KEY_STATUSDESCR, SVS_NORMAL, hContact != NULL);
+ }
+ else switch((char)db_get_b(hContact, gg->m_szModuleName, "Gender", (BYTE)'?'))
+ {
+ case 'F':
+ SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0);
+ break;
+ case 'M':
+ SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0);
+ break;
+ default:
+ SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0);
+ }
+
+ // Disable when updating
+ if (dat) dat->disableUpdate = FALSE;
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ if (dat && !dat->hContact && LOWORD(wParam) == IDC_SAVE && HIWORD(wParam) == BN_CLICKED)
+ {
+ // Save user data
+ char text[256];
+ gg_pubdir50_t req;
+ GGPROTO *gg = dat->gg;
+
+ if (!gg->isonline())
+ {
+ MessageBox(NULL,
+ TranslateT("You have to be logged in before you can change your details."),
+ gg->m_tszUserName, MB_OK | MB_ICONSTOP);
+ break;
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), FALSE);
+
+ req = gg_pubdir50_new(GG_PUBDIR50_WRITE);
+
+ GetDlgItemTextA(hwndDlg, IDC_FIRSTNAME, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, text);
+
+ GetDlgItemTextA(hwndDlg, IDC_LASTNAME, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, text);
+
+ GetDlgItemTextA(hwndDlg, IDC_NICKNAME, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, text);
+
+ GetDlgItemTextA(hwndDlg, IDC_CITY, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_CITY, text);
+
+ // Gadu-Gadu Female <-> Male
+ switch(SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_GETCURSEL, 0, 0))
+ {
+ case 1:
+ gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_FEMALE);
+ break;
+ case 2:
+ gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_SET_MALE);
+ break;
+ default:
+ gg_pubdir50_add(req, GG_PUBDIR50_GENDER, "");
+ }
+
+ GetDlgItemTextA(hwndDlg, IDC_BIRTHYEAR, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, text);
+
+ GetDlgItemTextA(hwndDlg, IDC_FAMILYNAME, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FAMILYNAME, text);
+
+ GetDlgItemTextA(hwndDlg, IDC_CITYORIGIN, text, sizeof(text));
+ if (strlen(text)) gg_pubdir50_add(req, GG_PUBDIR50_FAMILYCITY, text);
+
+ // Run update
+ gg_pubdir50_seq_set(req, GG_SEQ_CHINFO);
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_pubdir50(gg->sess, req);
+ LeaveCriticalSection(&gg->sess_mutex);
+ dat->updating = TRUE;
+
+ gg_pubdir50_free(req);
+ }
+
+ if (dat && !dat->hContact && !dat->disableUpdate && (HIWORD(wParam) == EN_CHANGE && (
+ LOWORD(wParam) == IDC_NICKNAME || LOWORD(wParam) == IDC_FIRSTNAME || LOWORD(wParam) == IDC_LASTNAME || LOWORD(wParam) == IDC_FAMILYNAME ||
+ LOWORD(wParam) == IDC_CITY || LOWORD(wParam) == IDC_CITYORIGIN || LOWORD(wParam) == IDC_BIRTHYEAR) ||
+ HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_GENDER))
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAVE), TRUE);
+
+ switch(LOWORD(wParam)) {
+ case IDCANCEL:
+ SendMessage(GetParent(hwndDlg),msg,wParam,lParam);
+ break;
+ }
+ break;
+
+ case WM_DESTROY:
+ if (dat) mir_free(dat);
+ break;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Info Page : Init
+
+int GGPROTO::details_init(WPARAM wParam, LPARAM lParam)
+{
+ char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, lParam, 0);
+ if ((szProto == NULL || strcmp(szProto, m_szModuleName)) && lParam || lParam && db_get_b((HANDLE)lParam, m_szModuleName, "ChatRoom", 0))
+ return 0;
+
+ // Here goes init
+ {
+ OPTIONSDIALOGPAGE odp = {0};
+
+ odp.cbSize = sizeof(odp);
+ odp.flags = ODPF_DONTTRANSLATE | ODPF_TCHAR;
+ odp.hInstance = hInstance;
+ odp.pfnDlgProc = gg_detailsdlgproc;
+ odp.position = -1900000000;
+ odp.pszTemplate = ((HANDLE)lParam != NULL) ? MAKEINTRESOURCEA(IDD_INFO_GG) : MAKEINTRESOURCEA(IDD_CHINFO_GG);
+ odp.ptszTitle = m_tszUserName;
+ odp.dwInitParam = (LPARAM)this;
+ UserInfo_AddPage(wParam, &odp);
+ }
+
+ // Start search for user data
+ if ((HANDLE)lParam == NULL)
+ GetInfo(NULL, 0);
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+// Proc: Account manager options dialog
+INT_PTR CALLBACK gg_acc_mgr_guidlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+////////////////////////////////////////////////////////////////////////////////////////////
+{
+ GGPROTO *gg = (GGPROTO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+ DWORD num;
+ GGPROTO *gg = (GGPROTO *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
+
+ TranslateDialogDefault(hwndDlg);
+ if (num = db_get_b(NULL, gg->m_szModuleName, GG_KEY_UIN, 0))
+ SetDlgItemTextA(hwndDlg, IDC_UIN, ditoa(num));
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ)) {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, &dbv, DBVT_ASCIIZ)) {
+ SetDlgItemTextA(hwndDlg, IDC_EMAIL, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_CREATEACCOUNT:
+ {
+ // Readup data
+ GGUSERUTILDLGDATA dat;
+ int ret;
+ char pass[128], email[128];
+ GetDlgItemTextA(hwndDlg, IDC_UIN, pass, sizeof(pass));
+ dat.uin = atoi(pass);
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
+ GetDlgItemTextA(hwndDlg, IDC_EMAIL, email, sizeof(email));
+ dat.pass = pass;
+ dat.email = email;
+ dat.gg = gg;
+ dat.mode = GG_USERUTIL_CREATE;
+ ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CREATEACCOUNT), hwndDlg, gg_userutildlgproc, (LPARAM)&dat);
+
+ if (ret == IDOK)
+ {
+ DBVARIANT dbv;
+ DWORD num;
+ // Show reload required window
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RELOADREQD), SW_SHOW);
+
+ // Update uin
+ if (num = db_get_b(NULL, gg->m_szModuleName, GG_KEY_UIN, 0))
+ SetDlgItemTextA(hwndDlg, IDC_UIN, ditoa(num));
+ else
+ SetDlgItemTextA(hwndDlg, IDC_UIN, "");
+
+ // Update password
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ)) {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else SetDlgItemTextA(hwndDlg, IDC_PASSWORD, "");
+
+ // Update e-mail
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, &dbv, DBVT_ASCIIZ)) {
+ SetDlgItemTextA(hwndDlg, IDC_EMAIL, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else SetDlgItemTextA(hwndDlg, IDC_EMAIL, "");
+ }
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ char str[128];
+ uin_t uin;
+
+ // Write Gadu-Gadu number & password
+ GetDlgItemTextA(hwndDlg, IDC_UIN, str, sizeof(str));
+ uin = atoi(str);
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, str, sizeof(str));
+ CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(str), (LPARAM) str);
+ gg->checknewuser(uin, str);
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_UIN, uin);
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, str);
+
+ // Write Gadu-Gadu email
+ GetDlgItemTextA(hwndDlg, IDC_EMAIL, str, sizeof(str));
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, str);
+ }
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/protocols/Gadu-Gadu/dynstuff.c b/protocols/Gadu-Gadu/dynstuff.cpp
index d90c4e7908..9ae41daf59 100644
--- a/protocols/Gadu-Gadu/dynstuff.c
+++ b/protocols/Gadu-Gadu/dynstuff.cpp
@@ -40,34 +40,33 @@
*/
void *list_add_sorted(list_t *list, void *data, int alloc_size, int (*comparision)(void *, void *))
{
- list_t new, tmp;
-
if (!list) {
errno = EFAULT;
return NULL;
}
- new = malloc(sizeof(struct list));
+ list_t newlist = (list_t)malloc(sizeof(struct list));
- new->data = data;
- new->next = NULL;
+ newlist->data = data;
+ newlist->next = NULL;
if (alloc_size) {
- new->data = malloc(alloc_size);
- memcpy(new->data, data, alloc_size);
+ newlist->data = malloc(alloc_size);
+ memcpy(newlist->data, data, alloc_size);
}
+ list_t tmp;
if (!(tmp = *list)) {
- *list = new;
+ *list = newlist;
} else {
if (!comparision) {
while (tmp->next)
tmp = tmp->next;
- tmp->next = new;
+ tmp->next = newlist;
} else {
list_t prev = NULL;
- while (comparision(new->data, tmp->data) > 0) {
+ while (comparision(newlist->data, tmp->data) > 0) {
prev = tmp;
tmp = tmp->next;
if (!tmp)
@@ -76,16 +75,16 @@ void *list_add_sorted(list_t *list, void *data, int alloc_size, int (*comparisio
if (!prev) {
tmp = *list;
- *list = new;
- new->next = tmp;
+ *list = newlist;
+ newlist->next = tmp;
} else {
- prev->next = new;
- new->next = tmp;
+ prev->next = newlist;
+ newlist->next = tmp;
}
}
}
- return new->data;
+ return newlist->data;
}
/*
@@ -194,7 +193,7 @@ static void string_realloc(string_t s, int count)
if (s->str && count + 1 <= s->size)
return;
- tmp = realloc(s->str, count + 81);
+ tmp = (char*)realloc(s->str, count + 81);
if (!s->str)
*tmp = 0;
tmp[count + 80] = 0;
@@ -305,7 +304,7 @@ void string_insert(string_t s, int index, const char *str)
*/
string_t string_init(const char *value)
{
- string_t tmp = malloc(sizeof(struct string));
+ string_t tmp = (string_t)malloc(sizeof(struct string));
if (!value)
value = "";
@@ -330,7 +329,7 @@ void string_clear(string_t s)
return;
if (s->size > 160) {
- s->str = realloc(s->str, 80);
+ s->str = (char*)realloc(s->str, 80);
s->size = 80;
}
@@ -378,6 +377,7 @@ char *string_free(string_t s, int free_string)
*
* zwraca adres do bufora, którego _NIE_NALE¯Y_ zwalniaæ.
*/
+
const char *ditoa(long int i)
{
static char bufs[10][16];
@@ -388,7 +388,6 @@ const char *ditoa(long int i)
index = 0;
mir_snprintf(tmp, 16, "%ld", i);
-
return tmp;
}
@@ -444,7 +443,7 @@ char **array_make(const char *string, const char *sep, int max, int trim, int qu
break;
}
- if ((token = calloc(1, len + 1))) {
+ if ((token = (char*)calloc(1, len + 1))) {
char *r = token;
for (q = p + 1; *q; q++, r++) {
@@ -480,13 +479,13 @@ char **array_make(const char *string, const char *sep, int max, int trim, int qu
} else {
for (q = p, len = 0; *q && (last || !strchr(sep, *q)); q++, len++);
- token = calloc(1, len + 1);
+ token = (char*)calloc(1, len + 1);
strncpy(token, p, len);
token[len] = 0;
p = q;
}
- result = realloc(result, (items + 2) * sizeof(char*));
+ result = (char**)realloc(result, (items + 2) * sizeof(char*));
result[items] = token;
result[++items] = NULL;
@@ -498,7 +497,7 @@ char **array_make(const char *string, const char *sep, int max, int trim, int qu
failure:
if (!items)
- result = calloc(1, sizeof(char*));
+ result = (char**)calloc(1, sizeof(char*));
return result;
}
@@ -532,7 +531,7 @@ void array_add(char ***array, char *string)
{
int count = array_count(*array);
- *array = realloc(*array, (count + 2) * sizeof(char*));
+ *array = (char**)realloc(*array, (count + 2) * sizeof(char*));
(*array)[count + 1] = NULL;
(*array)[count] = string;
}
diff --git a/protocols/Gadu-Gadu/filetransfer.c b/protocols/Gadu-Gadu/filetransfer.cpp
index cc55b993b8..4c58c59b15 100644
--- a/protocols/Gadu-Gadu/filetransfer.c
+++ b/protocols/Gadu-Gadu/filetransfer.cpp
@@ -23,54 +23,52 @@
#include <io.h>
#include <fcntl.h>
-void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty);
-
-void gg_dccstart(GGPROTO *gg)
+void GGPROTO::dccstart()
{
DWORD exitCode = 0;
- if(gg->dcc) return;
+ if (dcc) return;
// Startup dcc thread
- GetExitCodeThread(gg->pth_dcc.hThread, &exitCode);
+ GetExitCodeThread(pth_dcc.hThread, &exitCode);
// Check if dcc thread isn't running already
- if(exitCode == STILL_ACTIVE)
+ if (exitCode == STILL_ACTIVE)
{
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dccstart(): DCC thread still active. Exiting...");
+ netlog("gg_dccstart(): DCC thread still active. Exiting...");
#endif
// Signalize mainthread it's started
- if(gg->event) SetEvent(gg->event);
+ if (hEvent) SetEvent(hEvent);
return;
}
// Check if we wan't direct connections
- if (!DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_DIRECTCONNS, GG_KEYDEF_DIRECTCONNS))
+ if (!db_get_b(NULL, m_szModuleName, GG_KEY_DIRECTCONNS, GG_KEYDEF_DIRECTCONNS))
{
- gg_netlog(gg, "gg_dccstart(): No direct connections setup.");
- if(gg->event) SetEvent(gg->event);
+ netlog("gg_dccstart(): No direct connections setup.");
+ if (hEvent) SetEvent(hEvent);
return;
}
// Start thread
- gg->pth_dcc.hThread = gg_forkthreadex(gg, gg_dccmainthread, NULL, &gg->pth_dcc.dwThreadId);
+ pth_dcc.hThread = forkthreadex(&GGPROTO::dccmainthread, NULL, &pth_dcc.dwThreadId);
}
-void gg_dccconnect(GGPROTO *gg, uin_t uin)
+void GGPROTO::dccconnect(uin_t uin)
{
struct gg_dcc *dcc;
- HANDLE hContact = gg_getcontact(gg, uin, 0, 0, NULL);
+ HANDLE hContact = getcontact(uin, 0, 0, NULL);
DWORD ip, myuin; WORD port;
- gg_netlog(gg, "gg_dccconnect(): Connecting to uin %d.", uin);
+ netlog("gg_dccconnect(): Connecting to uin %d.", uin);
// If unknown user or not on list ignore
if (!hContact) return;
// Read user IP and port
- ip = swap32(DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_CLIENTIP, 0));
- port = DBGetContactSettingWord(hContact, GG_PROTO, GG_KEY_CLIENTPORT, 0);
- myuin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0);
+ ip = swap32(db_get_b(hContact, m_szModuleName, GG_KEY_CLIENTIP, 0));
+ port = db_get_w(hContact, m_szModuleName, GG_KEY_CLIENTPORT, 0);
+ myuin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0);
// If not port nor ip nor my uin (?) specified
if (!ip || !port || !uin) return;
@@ -79,9 +77,9 @@ void gg_dccconnect(GGPROTO *gg, uin_t uin)
return;
// Add client dcc to watches
- EnterCriticalSection(&gg->ft_mutex);
- list_add(&gg->watches, dcc, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ list_add(&watches, dcc, 0);
+ LeaveCriticalSection(&ft_mutex);
}
//////////////////////////////////////////////////////////
@@ -91,24 +89,26 @@ struct ftfaildata
HANDLE hContact;
HANDLE hProcess;
};
-void __cdecl gg_ftfailthread(GGPROTO *gg, void *param)
+
+void __cdecl GGPROTO::ftfailthread(void *param)
{
struct ftfaildata *ft = (struct ftfaildata *)param;
SleepEx(100, FALSE);
- gg_netlog(gg, "gg_ftfailthread(): Sending failed file transfer.");
- ProtoBroadcastAck(GG_PROTO, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft->hProcess, 0);
+ netlog("gg_ftfailthread(): Sending failed file transfer.");
+ ProtoBroadcastAck(m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft->hProcess, 0);
free(ft);
}
+
HANDLE ftfail(GGPROTO *gg, HANDLE hContact)
{
- struct ftfaildata *ft = malloc(sizeof(struct ftfaildata));
+ ftfaildata *ft = (ftfaildata*)malloc(sizeof(struct ftfaildata));
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_ftfail(): Failing file transfer...");
+ gg->netlog("gg_ftfail(): Failing file transfer...");
#endif
srand(time(NULL));
ft->hProcess = (HANDLE)rand();
ft->hContact = hContact;
- gg_forkthread(gg, gg_ftfailthread, ft);
+ gg->forkthread(&GGPROTO::ftfailthread, ft);
return ft->hProcess;
}
@@ -118,10 +118,10 @@ HANDLE ftfail(GGPROTO *gg, HANDLE hContact)
// Info refresh min time (msec) / half-sec
#define GGSTATREFRESHEVERY 500
-void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
+void __cdecl GGPROTO::dccmainthread(void*)
{
uin_t uin;
- struct gg_event *e;
+ gg_event *e;
struct timeval tv;
fd_set rd, wd;
int ret;
@@ -131,39 +131,39 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
char filename[MAX_PATH];
// Zero up lists
- gg->watches = gg->transfers = gg->requests = l = NULL;
+ watches = transfers = requests = l = NULL;
- gg_netlog(gg, "gg_dccmainthread(): DCC Server Thread Starting");
+ netlog("gg_dccmainthread(): DCC Server Thread Starting");
// Readup number
- if (!(uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0)))
+ if (!(uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0)))
{
- gg_netlog(gg, "gg_dccmainthread(): No Gadu-Gadu number specified. Exiting.");
- if(gg->event) SetEvent(gg->event);
+ netlog("gg_dccmainthread(): No Gadu-Gadu number specified. Exiting.");
+ if (hEvent) SetEvent(hEvent);
return;
}
// Create listen socket on config direct port
- if (!(gg->dcc = gg_dcc_socket_create(uin, (uint16_t)DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_DIRECTPORT, GG_KEYDEF_DIRECTPORT))))
+ if (!(dcc = gg_dcc_socket_create(uin, (uint16_t)db_get_w(NULL, m_szModuleName, GG_KEY_DIRECTPORT, GG_KEYDEF_DIRECTPORT))))
{
- gg_netlog(gg, "gg_dccmainthread(): Cannot create DCC listen socket. Exiting.");
+ netlog("gg_dccmainthread(): Cannot create DCC listen socket. Exiting.");
// Signalize mainthread we haven't start
- if(gg->event) SetEvent(gg->event);
+ if (hEvent) SetEvent(hEvent);
return;
}
- gg_dcc_port = gg->dcc->port;
+ gg_dcc_port = dcc->port;
gg_dcc_ip = inet_addr("255.255.255.255");
- gg_netlog(gg, "gg_dccmainthread(): Listening on port %d.", gg_dcc_port);
+ netlog("gg_dccmainthread(): Listening on port %d.", gg_dcc_port);
// Signalize mainthread we started
- if(gg->event) SetEvent(gg->event);
+ if (hEvent) SetEvent(hEvent);
// Add main dcc handler to watches
- list_add(&gg->watches, gg->dcc, 0);
+ list_add(&watches, dcc, 0);
// Do while we are in the main server thread
- while(gg->pth_dcc.dwThreadId && gg->dcc)
+ while(pth_dcc.dwThreadId && dcc)
{
// Timeouts
tv.tv_sec = 1;
@@ -173,9 +173,9 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
FD_ZERO(&rd);
FD_ZERO(&wd);
- for (maxfd = 0, l = gg->watches; l; l = l->next)
+ for (maxfd = 0, l = watches; l; l = l->next)
{
- struct gg_common *w = l->data;
+ gg_common *w = (gg_common*)l->data;
if (!w || w->state == GG_STATE_ERROR || w->state == GG_STATE_IDLE || w->state == GG_STATE_DONE)
continue;
@@ -198,20 +198,20 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
if (ret == -1)
{
if (errno == EBADF)
- gg_netlog(gg, "gg_dccmainthread(): Bad descriptor on select().");
+ netlog("gg_dccmainthread(): Bad descriptor on select().");
else if (errno != EINTR)
- gg_netlog(gg, "gg_dccmainthread(): Unknown error on select().");
+ netlog("gg_dccmainthread(): Unknown error on select().");
continue;
}
// Process watches (carefull with l)
- l = gg->watches;
- EnterCriticalSection(&gg->ft_mutex);
+ l = watches;
+ EnterCriticalSection(&ft_mutex);
while (l)
{
- struct gg_common *c = l->data;
- struct gg_dcc *dcc = l->data;
- struct gg_dcc7 *dcc7 = l->data;
+ struct gg_common *c = (gg_common*)l->data;
+ struct gg_dcc *dcc = (gg_dcc*)l->data;
+ struct gg_dcc7 *dcc7 = (gg_dcc7*)l->data;
l = l->next;
switch (c->type)
@@ -226,34 +226,34 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
// Connection broken/closed
if (!(e = gg_dcc_socket_watch_fd(dcc)))
{
- gg_netlog(gg, "gg_dccmainthread(): Socket closed.");
+ netlog("gg_dccmainthread(): Socket closed.");
// Remove socket and _close
- list_remove(&gg->watches, dcc, 0);
+ list_remove(&watches, dcc, 0);
gg_dcc_socket_free(dcc);
// Check if it's main socket
- if(dcc == gg->dcc) gg->dcc = NULL;
+ if (dcc == dcc) dcc = NULL;
continue;
}
- else gg_netlog(gg, "gg_dccmainthread(): Event: %s", ggdebug_eventtype(e));
+ else netlog("gg_dccmainthread(): Event: %s", ggdebug_eventtype(e));
switch(e->type)
{
// Client connected
case GG_EVENT_DCC_NEW:
- list_add(&gg->watches, e->event.dcc_new, 0);
+ list_add(&watches, e->event.dcc_new, 0);
e->event.dcc_new = NULL;
break;
//
case GG_EVENT_NONE:
// If transfer in progress do status
- if(dcc->file_fd != -1 && dcc->offset > 0 && (((tick = GetTickCount()) - dcc->tick) > GGSTATREFRESHEVERY))
+ if (dcc->file_fd != -1 && dcc->offset > 0 && (((tick = GetTickCount()) - dcc->tick) > GGSTATREFRESHEVERY))
{
PROTOFILETRANSFERSTATUS pfts;
dcc->tick = tick;
strncpy(filename, dcc->folder, sizeof(filename));
- strncat(filename, dcc->file_info.filename, sizeof(filename) - strlen(filename));
+ strncat(filename, (char*)dcc->file_info.filename, sizeof(filename) - strlen(filename));
memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
pfts.hContact = (HANDLE)dcc->contact;
@@ -268,21 +268,21 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
pfts.currentFileSize = dcc->file_info.size;
pfts.currentFileProgress = dcc->offset;
pfts.currentFileTime = 0;
- ProtoBroadcastAck(GG_PROTO, dcc->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc, (LPARAM)&pfts);
+ ProtoBroadcastAck(m_szModuleName, dcc->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc, (LPARAM)&pfts);
}
break;
// Connection was successfuly ended
case GG_EVENT_DCC_DONE:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Transfer done ! Closing connection.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Transfer done ! Closing connection.", dcc->peer_uin);
// Remove from watches
- list_remove(&gg->watches, dcc, 0);
+ list_remove(&watches, dcc, 0);
// Close file & success
- if(dcc->file_fd != -1)
+ if (dcc->file_fd != -1)
{
PROTOFILETRANSFERSTATUS pfts;
strncpy(filename, dcc->folder, sizeof(filename));
- strncat(filename, dcc->file_info.filename, sizeof(filename) - strlen(filename));
+ strncat(filename, (char*)dcc->file_info.filename, sizeof(filename) - strlen(filename));
memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
pfts.hContact = (HANDLE)dcc->contact;
@@ -297,12 +297,12 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
pfts.currentFileSize = dcc->file_info.size;
pfts.currentFileProgress = dcc->file_info.size;
pfts.currentFileTime = 0;
- ProtoBroadcastAck(GG_PROTO, dcc->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc, (LPARAM)&pfts);
+ ProtoBroadcastAck(m_szModuleName, dcc->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc, (LPARAM)&pfts);
_close(dcc->file_fd); dcc->file_fd = -1;
- ProtoBroadcastAck(GG_PROTO, dcc->contact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dcc, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc->contact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dcc, 0);
}
// Free dcc
- gg_free_dcc(dcc); if(dcc == gg->dcc) gg->dcc = NULL;
+ gg_free_dcc(dcc); if (dcc == dcc) dcc = NULL;
break;
// Client error
@@ -310,47 +310,47 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
switch (e->event.dcc_error)
{
case GG_ERROR_DCC_HANDSHAKE:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Handshake error.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Handshake error.", dcc->peer_uin);
break;
case GG_ERROR_DCC_NET:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Network error.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Network error.", dcc->peer_uin);
break;
case GG_ERROR_DCC_FILE:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, File read/write error.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, File read/write error.", dcc->peer_uin);
break;
case GG_ERROR_DCC_EOF:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, End of file/connection error.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, End of file/connection error.", dcc->peer_uin);
break;
case GG_ERROR_DCC_REFUSED:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Connection refused error.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Connection refused error.", dcc->peer_uin);
break;
default:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Unknown error.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Unknown error.", dcc->peer_uin);
}
// Don't do anything if it's main socket
- if(dcc == gg->dcc) break;
+ if (dcc == dcc) break;
// Remove from watches
- list_remove(&gg->watches, dcc, 0);
+ list_remove(&watches, dcc, 0);
// Close file & fail
- if(dcc->contact)
+ if (dcc->contact)
{
_close(dcc->file_fd); dcc->file_fd = -1;
- ProtoBroadcastAck(GG_PROTO, dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc, 0);
}
// Free dcc
- gg_free_dcc(dcc); if(dcc == gg->dcc) gg->dcc = NULL;
+ gg_free_dcc(dcc); if (dcc == dcc) dcc = NULL;
break;
// Need file acknowledgement
case GG_EVENT_DCC_NEED_FILE_ACK:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, File ack filename \"%s\" size %d.", dcc->peer_uin,
+ netlog("gg_dccmainthread(): Client: %d, File ack filename \"%s\" size %d.", dcc->peer_uin,
dcc->file_info.filename, dcc->file_info.size);
// Do not watch for transfer until user accept it
- list_remove(&gg->watches, dcc, 0);
+ list_remove(&watches, dcc, 0);
// Add to waiting transfers
- list_add(&gg->transfers, dcc, 0);
+ list_add(&transfers, dcc, 0);
//////////////////////////////////////////////////
// Add file recv request
@@ -358,11 +358,11 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
CCSDATA ccs;
PROTORECVEVENT pre;
char *szBlob;
- char *szFilename = dcc->file_info.filename;
- char *szMsg = dcc->file_info.filename;
+ char *szFilename = (char*)dcc->file_info.filename;
+ char *szMsg = (char*)dcc->file_info.filename;
// Make new ggtransfer struct
- dcc->contact = gg_getcontact(gg, dcc->peer_uin, 0, 0, NULL);
+ dcc->contact = getcontact(dcc->peer_uin, 0, 0, NULL);
szBlob = (char *)malloc(sizeof(DWORD) + strlen(szFilename) + strlen(szMsg) + 2);
// Store current dcc
*(PDWORD)szBlob = (DWORD)dcc;
@@ -385,26 +385,26 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
// Need client accept
case GG_EVENT_DCC_CLIENT_ACCEPT:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Client accept.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Client accept.", dcc->peer_uin);
// Check if user is on the list and if it is my uin
- if(gg_getcontact(gg, dcc->peer_uin, 0, 0, NULL) &&
- DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, -1) == dcc->uin)
+ if (getcontact(dcc->peer_uin, 0, 0, NULL) &&
+ db_get_b(NULL, m_szModuleName, GG_KEY_UIN, -1) == dcc->uin)
break;
// Kill unauthorized dcc
- list_remove(&gg->watches, dcc, 0);
- gg_free_dcc(dcc); if(dcc == gg->dcc) gg->dcc = NULL;
+ list_remove(&watches, dcc, 0);
+ gg_free_dcc(dcc); if (dcc == dcc) dcc = NULL;
break;
// Client connected as we wished to (callback)
case GG_EVENT_DCC_CALLBACK:
{
int found = 0;
- gg_netlog(gg, "gg_dccmainthread(): Callback from client %d.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Callback from client %d.", dcc->peer_uin);
// Seek for stored callback request
- for (l = gg->requests; l; l = l->next)
+ for (l = requests; l; l = l->next)
{
- struct gg_dcc *req = l->data;
+ struct gg_dcc *req = (gg_dcc*)l->data;
if (req && req->peer_uin == dcc->peer_uin)
{
@@ -420,14 +420,14 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
memcpy(req, dcc, sizeof(struct gg_dcc));
// Remove request
- list_remove(&gg->requests, req, 0);
+ list_remove(&requests, req, 0);
// Remove dcc from watches
- list_remove(&gg->watches, dcc, 0);
+ list_remove(&watches, dcc, 0);
// Add request to watches
- list_add(&gg->watches, req, 0);
+ list_add(&watches, req, 0);
// Free old dat
gg_free_dcc(dcc);
- gg_netlog(gg, "gg_dccmainthread(): Found stored request to client %d, filename \"%s\" size %d, folder \"%s\".",
+ netlog("gg_dccmainthread(): Found stored request to client %d, filename \"%s\" size %d, folder \"%s\".",
req->peer_uin, req->file_info.filename, req->file_info.size, req->folder);
break;
}
@@ -435,10 +435,10 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
if (!found)
{
- gg_netlog(gg, "gg_dccmainthread(): Unknown request to client %d.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Unknown request to client %d.", dcc->peer_uin);
// Kill unauthorized dcc
- list_remove(&gg->watches, dcc, 0);
- gg_free_dcc(dcc); if(dcc == gg->dcc) gg->dcc = NULL;
+ list_remove(&watches, dcc, 0);
+ gg_free_dcc(dcc); if (dcc == dcc) dcc = NULL;
}
break;
}
@@ -461,25 +461,25 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
// Connection broken/closed
if (!(e = gg_dcc7_watch_fd(dcc7)))
{
- gg_netlog(gg, "gg_dccmainthread(): Socket closed.");
+ netlog("gg_dccmainthread(): Socket closed.");
// Remove socket and _close
- list_remove(&gg->watches, dcc7, 0);
+ list_remove(&watches, dcc7, 0);
gg_dcc7_free(dcc7);
continue;
}
- else gg_netlog(gg, "gg_dccmainthread(): Event: %s", ggdebug_eventtype(e));
+ else netlog("gg_dccmainthread(): Event: %s", ggdebug_eventtype(e));
switch(e->type)
{
//
case GG_EVENT_NONE:
// If transfer in progress do status
- if(dcc7->file_fd != -1 && dcc7->offset > 0 && (((tick = GetTickCount()) - dcc7->tick) > GGSTATREFRESHEVERY))
+ if (dcc7->file_fd != -1 && dcc7->offset > 0 && (((tick = GetTickCount()) - dcc7->tick) > GGSTATREFRESHEVERY))
{
PROTOFILETRANSFERSTATUS pfts;
dcc7->tick = tick;
strncpy(filename, dcc7->folder, sizeof(filename));
- strncat(filename, dcc7->filename, sizeof(filename) - strlen(filename));
+ strncat(filename, (char*)dcc7->filename, sizeof(filename) - strlen(filename));
memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
pfts.hContact = (HANDLE)dcc7->contact;
@@ -494,21 +494,21 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
pfts.currentFileSize = dcc7->size;
pfts.currentFileProgress = dcc7->offset;
pfts.currentFileTime = 0;
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc7, (LPARAM)&pfts);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc7, (LPARAM)&pfts);
}
break;
// Connection was successfuly ended
case GG_EVENT_DCC7_DONE:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Transfer done ! Closing connection.", dcc->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Transfer done ! Closing connection.", dcc->peer_uin);
// Remove from watches
- list_remove(&gg->watches, dcc7, 0);
+ list_remove(&watches, dcc7, 0);
// Close file & success
- if(dcc7->file_fd != -1)
+ if (dcc7->file_fd != -1)
{
PROTOFILETRANSFERSTATUS pfts;
strncpy(filename, dcc7->folder, sizeof(filename));
- strncat(filename, dcc7->filename, sizeof(filename) - strlen(filename));
+ strncat(filename, (char*)dcc7->filename, sizeof(filename) - strlen(filename));
memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS));
pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS);
pfts.hContact = (HANDLE)dcc7->contact;
@@ -523,9 +523,9 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
pfts.currentFileSize = dcc7->size;
pfts.currentFileProgress = dcc7->size;
pfts.currentFileTime = 0;
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc7, (LPARAM)&pfts);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DATA, dcc7, (LPARAM)&pfts);
_close(dcc7->file_fd); dcc7->file_fd = -1;
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dcc7, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dcc7, 0);
}
// Free dcc
gg_dcc7_free(dcc7);
@@ -536,28 +536,28 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
switch (e->event.dcc7_error)
{
case GG_ERROR_DCC7_HANDSHAKE:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Handshake error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Handshake error.", dcc7->peer_uin);
break;
case GG_ERROR_DCC7_NET:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Network error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Network error.", dcc7->peer_uin);
break;
case GG_ERROR_DCC7_FILE:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, File read/write error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, File read/write error.", dcc7->peer_uin);
break;
case GG_ERROR_DCC7_EOF:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, End of file/connection error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, End of file/connection error.", dcc7->peer_uin);
break;
case GG_ERROR_DCC7_REFUSED:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Connection refused error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Connection refused error.", dcc7->peer_uin);
break;
case GG_ERROR_DCC7_RELAY:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Relay connection error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Relay connection error.", dcc7->peer_uin);
break;
default:
- gg_netlog(gg, "gg_dccmainthread(): Client: %d, Unknown error.", dcc7->peer_uin);
+ netlog("gg_dccmainthread(): Client: %d, Unknown error.", dcc7->peer_uin);
}
// Remove from watches
- list_remove(&gg->watches, dcc7, 0);
+ list_remove(&watches, dcc7, 0);
// Close file & fail
if (dcc7->file_fd != -1)
@@ -567,7 +567,7 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
}
if (dcc7->contact)
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
// Free dcc
gg_dcc7_free(dcc7);
@@ -579,197 +579,79 @@ void __cdecl gg_dccmainthread(GGPROTO *gg, void *empty)
break;
}
}
- LeaveCriticalSection(&gg->ft_mutex);
+ LeaveCriticalSection(&ft_mutex);
}
// Close all dcc client sockets
- for (l = gg->watches; l; l = l->next)
+ for (l = watches; l; l = l->next)
{
- struct gg_common *c = l->data;
+ struct gg_common *c = (gg_common*)l->data;
if (!c) continue;
if (c->type == GG_SESSION_DCC7_SOCKET || c->type == GG_SESSION_DCC7_SEND || c->type == GG_SESSION_DCC7_GET)
{
- struct gg_dcc7 *dcc7 = l->data;
+ struct gg_dcc7 *dcc7 = (gg_dcc7*)l->data;
gg_dcc7_free(dcc7);
}
else
{
- struct gg_dcc *dcc = l->data;
+ struct gg_dcc *dcc = (gg_dcc*)l->data;
gg_dcc_socket_free(dcc);
// Check if it's main socket
- if(dcc == gg->dcc) gg->dcc = NULL;
+ if (dcc == dcc) dcc = NULL;
}
}
// Close all waiting for aknowledgle transfers
- for (l = gg->transfers; l; l = l->next)
+ for (l = transfers; l; l = l->next)
{
- struct gg_common *c = l->data;
+ struct gg_common *c = (gg_common*)l->data;
if (!c) continue;
if (c->type == GG_SESSION_DCC7_SOCKET || c->type == GG_SESSION_DCC7_SEND || c->type == GG_SESSION_DCC7_GET)
{
- struct gg_dcc7 *dcc7 = l->data;
+ struct gg_dcc7 *dcc7 = (gg_dcc7*)l->data;
gg_dcc7_free(dcc7);
}
else
{
- struct gg_dcc *dcc = l->data;
+ struct gg_dcc *dcc = (gg_dcc*)l->data;
gg_dcc_socket_free(dcc);
}
}
// Close all waiting dcc requests
- for (l = gg->requests; l; l = l->next)
+ for (l = requests; l; l = l->next)
{
- struct gg_dcc *dcc = l->data;
- if(dcc) gg_free_dcc(dcc);
+ struct gg_dcc *dcc = (gg_dcc*)l->data;
+ if (dcc) gg_free_dcc(dcc);
}
- list_destroy(gg->watches, 0);
- list_destroy(gg->transfers, 0);
- list_destroy(gg->requests, 0);
+ list_destroy(watches, 0);
+ list_destroy(transfers, 0);
+ list_destroy(requests, 0);
gg_dcc_port = 0;
gg_dcc_ip = 0;
- gg_netlog(gg, "gg_dccmainthread(): DCC Server Thread Ending");
+ netlog("gg_dccmainthread(): DCC Server Thread Ending");
}
-////////////////////////////////////////////////////////////
-// Called when received an file
-int gg_recvfile(PROTO_INTERFACE *proto, HANDLE hContact, PROTOFILEEVENT* pre)
-{
- CCSDATA ccs = { hContact, PSR_FILE, 0, ( LPARAM )pre };
- return CallService( MS_PROTO_RECVFILE, 0, ( LPARAM )&ccs );
-}
-
-////////////////////////////////////////////////////////////
-// Called when user sends a file
-HANDLE gg_sendfile(PROTO_INTERFACE *proto, HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles)
-{
- GGPROTO *gg = (GGPROTO *) proto;
- char *bslash, *filename;
- struct gg_dcc *dcc;
- DWORD ip, ver;
- WORD port;
- uin_t myuin, uin;
-
- // Check if main dcc thread is on
- if (!gg_isonline(gg)) return ftfail(gg, hContact);
-
- filename = gg_t2a(ppszFiles[0]);
-
- // Read user IP and port
- ip = swap32(DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_CLIENTIP, 0));
- port = DBGetContactSettingWord(hContact, GG_PROTO, GG_KEY_CLIENTPORT, 0);
- myuin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0);
- uin = DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0);
- ver = DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_CLIENTVERSION, 0);
-
- // Use DCC7 if a contact is using at least version 7.6 or unknown version
- if ((ver & 0x00ffffff) >= 0x29 || !ver) {
- struct gg_dcc7 *dcc7;
-
- EnterCriticalSection(&gg->sess_mutex);
- if (!(dcc7 = gg_dcc7_send_file(gg->sess, uin, filename, NULL, NULL))) {
- LeaveCriticalSection(&gg->sess_mutex);
- gg_netlog(gg, "gg_sendfile(): Failed to send file \"%s\".", filename);
- mir_free(filename);
- return ftfail(gg, hContact);
- }
- LeaveCriticalSection(&gg->sess_mutex);
-
- gg_netlog(gg, "gg_sendfile(): Sending file \"%s\" to %d.", filename, uin);
-
- // Add dcc to watches
- list_add(&gg->watches, dcc7, 0);
-
- // Store handle
- dcc7->contact = hContact;
- dcc7->folder = _strdup(filename);
- dcc7->tick = 0;
- // Make folder name
- bslash = strrchr(dcc7->folder, '\\');
- if(bslash)
- *(bslash + 1) = 0;
- else
- *(dcc7->folder) = 0;
- mir_free(filename);
- return dcc7;
- }
-
- // Return if bad connection info
- if (!port || !uin || !myuin)
- {
- gg_netlog(gg, "gg_sendfile(): Bad contact uin or my uin. Exit.");
- mir_free(filename);
- return ftfail(gg, hContact);
- }
-
- // Try to connect if not ask user to connect me
- if ((ip && port >= 10 && !(dcc = gg_dcc_send_file(ip, port, myuin, uin))) || (port < 10 && port > 0))
- {
- // Make fake dcc structure
- dcc = malloc(sizeof(struct gg_dcc));
- memset(dcc, 0, sizeof(struct gg_dcc));
- // Fill up structures
- dcc->uin = myuin;
- dcc->peer_uin = uin;
- dcc->fd = -1;
- dcc->type = GG_SESSION_DCC_SEND;
- gg_netlog(gg, "gg_sendfile(): Requesting user to connect us and scheduling gg_dcc struct for a later use.");
- EnterCriticalSection(&gg->sess_mutex);
- gg_dcc_request(gg->sess, uin);
- LeaveCriticalSection(&gg->sess_mutex);
- list_add(&gg->requests, dcc, 0);
- }
-
- // Write filename
- if(gg_dcc_fill_file_info(dcc, filename) == -1)
- {
- gg_netlog(gg, "gg_sendfile(): Cannot open and file fileinfo \"%s\".", filename);
- gg_free_dcc(dcc);
- mir_free(filename);
- return ftfail(gg, hContact);
- }
-
- gg_netlog(gg, "gg_sendfile(): Sending file \"%s\" to %d in %s mode.", filename, uin, (dcc->fd != -1) ? "active" : "passive");
-
- // Add dcc to watches if not passive
- if(dcc->fd != -1) list_add(&gg->watches, dcc, 0);
-
- // Store handle
- dcc->contact = hContact;
- dcc->folder = _strdup(filename);
- dcc->tick = 0;
- // Make folder name
- bslash = strrchr(dcc->folder, '\\');
- if(bslash)
- *(bslash + 1) = 0;
- else
- *(dcc->folder) = 0;
-
- mir_free(filename);
- return dcc;
-}
-
-HANDLE gg_dccfileallow(GGPROTO *gg, HANDLE hTransfer, const PROTOCHAR* szPath)
+HANDLE GGPROTO::dccfileallow(HANDLE hTransfer, const PROTOCHAR* szPath)
{
struct gg_dcc *dcc = (struct gg_dcc *) hTransfer;
- char fileName[MAX_PATH], *path = gg_t2a(szPath);
+ char fileName[MAX_PATH], *path = mir_t2a(szPath);
strncpy(fileName, path, sizeof(fileName));
- strncat(fileName, dcc->file_info.filename, sizeof(fileName) - strlen(fileName));
+ strncat(fileName, (char*)dcc->file_info.filename, sizeof(fileName) - strlen(fileName));
dcc->folder = _strdup((char *) path);
dcc->tick = 0;
mir_free(path);
// Remove transfer from waiting list
- EnterCriticalSection(&gg->ft_mutex);
- list_remove(&gg->transfers, dcc, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ list_remove(&transfers, dcc, 0);
+ LeaveCriticalSection(&ft_mutex);
// Open file for appending and check if ok
if ((dcc->file_fd = _open(fileName, _O_WRONLY | _O_APPEND | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE)) == -1)
{
- gg_netlog(gg, "gg_dccfileallow(): Failed to create file \"%s\".", fileName);
- ProtoBroadcastAck(GG_PROTO, dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc, 0);
+ netlog("gg_dccfileallow(): Failed to create file \"%s\".", fileName);
+ ProtoBroadcastAck(m_szModuleName, dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc, 0);
// Free transfer
gg_free_dcc(dcc);
return 0;
@@ -779,35 +661,35 @@ HANDLE gg_dccfileallow(GGPROTO *gg, HANDLE hTransfer, const PROTOCHAR* szPath)
dcc->offset = _lseek(dcc->file_fd, 0, SEEK_END);
// Add to watches and start transfer
- EnterCriticalSection(&gg->ft_mutex);
- list_add(&gg->watches, dcc, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ list_add(&watches, dcc, 0);
+ LeaveCriticalSection(&ft_mutex);
- gg_netlog(gg, "gg_dccfileallow(): Receiving file \"%s\" from %d.", dcc->file_info.filename, dcc->peer_uin);
+ netlog("gg_dccfileallow(): Receiving file \"%s\" from %d.", dcc->file_info.filename, dcc->peer_uin);
return hTransfer;
}
-HANDLE gg_dcc7fileallow(GGPROTO *gg, HANDLE hTransfer, const PROTOCHAR* szPath)
+HANDLE GGPROTO::dcc7fileallow(HANDLE hTransfer, const PROTOCHAR* szPath)
{
struct gg_dcc7 *dcc7 = (struct gg_dcc7 *) hTransfer;
- char fileName[MAX_PATH], *path = gg_t2a(szPath);
+ char fileName[MAX_PATH], *path = mir_t2a(szPath);
int iFtRemoveRes;
strncpy(fileName, path, sizeof(fileName));
- strncat(fileName, dcc7->filename, sizeof(fileName) - strlen(fileName));
+ strncat(fileName, (char*)dcc7->filename, sizeof(fileName) - strlen(fileName));
dcc7->folder = _strdup((char *) path);
dcc7->tick = 0;
mir_free(path);
// Remove transfer from waiting list
- EnterCriticalSection(&gg->ft_mutex);
- iFtRemoveRes = list_remove(&gg->transfers, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ iFtRemoveRes = list_remove(&transfers, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
if (iFtRemoveRes == -1)
{
- gg_netlog(gg, "gg_dcc7fileallow(): File transfer denied.");
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DENIED, dcc7, 0);
+ netlog("gg_dcc7fileallow(): File transfer denied.");
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_DENIED, dcc7, 0);
// Free transfer
gg_dcc7_free(dcc7);
return 0;
@@ -816,9 +698,9 @@ HANDLE gg_dcc7fileallow(GGPROTO *gg, HANDLE hTransfer, const PROTOCHAR* szPath)
// Open file for appending and check if ok
if ((dcc7->file_fd = _open(fileName, _O_WRONLY | _O_APPEND | _O_BINARY | _O_CREAT, _S_IREAD | _S_IWRITE)) == -1)
{
- gg_netlog(gg, "gg_dcc7fileallow(): Failed to create file \"%s\".", fileName);
+ netlog("gg_dcc7fileallow(): Failed to create file \"%s\".", fileName);
gg_dcc7_reject(dcc7, GG_DCC7_REJECT_USER);
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
// Free transfer
gg_dcc7_free(dcc7);
return 0;
@@ -829,42 +711,27 @@ HANDLE gg_dcc7fileallow(GGPROTO *gg, HANDLE hTransfer, const PROTOCHAR* szPath)
gg_dcc7_accept(dcc7, dcc7->offset);
// Add to watches and start transfer
- EnterCriticalSection(&gg->ft_mutex);
- list_add(&gg->watches, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ list_add(&watches, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
- gg_netlog(gg, "gg_dcc7fileallow(): Receiving file \"%s\" from %d.", dcc7->filename, dcc7->peer_uin);
+ netlog("gg_dcc7fileallow(): Receiving file \"%s\" from %d.", dcc7->filename, dcc7->peer_uin);
return hTransfer;
}
-////////////////////////////////////////////////////////////
-// File receiving allowed
-HANDLE gg_fileallow(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath)
-{
- struct gg_common *c = (struct gg_common *) hTransfer;
-
- // Check if its proper dcc
- if (!c) return NULL;
-
- if (c->type == GG_SESSION_DCC7_GET)
- return gg_dcc7fileallow((GGPROTO *)proto, hTransfer, szPath);
-
- return gg_dccfileallow((GGPROTO *)proto, hTransfer, szPath);
-}
-
-int gg_dccfiledeny(GGPROTO *gg, HANDLE hTransfer)
+int GGPROTO::dccfiledeny(HANDLE hTransfer)
{
struct gg_dcc *dcc = (struct gg_dcc *) hTransfer;
// Remove transfer from any list
- EnterCriticalSection(&gg->ft_mutex);
- if(gg->watches) list_remove(&gg->watches, dcc, 0);
- if(gg->requests) list_remove(&gg->requests, dcc, 0);
- if(gg->transfers) list_remove(&gg->transfers, dcc, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ if (watches) list_remove(&watches, dcc, 0);
+ if (requests) list_remove(&requests, dcc, 0);
+ if (transfers) list_remove(&transfers, dcc, 0);
+ LeaveCriticalSection(&ft_mutex);
- gg_netlog(gg, "gg_dccfiledeny(): Rejected file \"%s\" from/to %d.", dcc->file_info.filename, dcc->peer_uin);
+ netlog("gg_dccfiledeny(): Rejected file \"%s\" from/to %d.", dcc->file_info.filename, dcc->peer_uin);
// Free transfer
gg_free_dcc(dcc);
@@ -872,19 +739,19 @@ int gg_dccfiledeny(GGPROTO *gg, HANDLE hTransfer)
return 0;
}
-int gg_dcc7filedeny(GGPROTO *gg, HANDLE hTransfer)
+int GGPROTO::dcc7filedeny(HANDLE hTransfer)
{
struct gg_dcc7 *dcc7 = (struct gg_dcc7 *) hTransfer;
gg_dcc7_reject(dcc7, GG_DCC7_REJECT_USER);
// Remove transfer from any list
- EnterCriticalSection(&gg->ft_mutex);
- if(gg->watches) list_remove(&gg->watches, dcc7, 0);
- if(gg->transfers) list_remove(&gg->transfers, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ if (watches) list_remove(&watches, dcc7, 0);
+ if (transfers) list_remove(&transfers, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
- gg_netlog(gg, "gg_dcc7filedeny(): Rejected file \"%s\" from/to %d.", dcc7->filename, dcc7->peer_uin);
+ netlog("gg_dcc7filedeny(): Rejected file \"%s\" from/to %d.", dcc7->filename, dcc7->peer_uin);
// Free transfer
gg_dcc7_free(dcc7);
@@ -892,42 +759,27 @@ int gg_dcc7filedeny(GGPROTO *gg, HANDLE hTransfer)
return 0;
}
-////////////////////////////////////////////////////////////
-// File receiving denied
-int gg_filedeny(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason)
-{
- struct gg_common *c = (struct gg_common *) hTransfer;
-
- // Check if its proper dcc
- if (!c) return 0;
-
- if (c->type == GG_SESSION_DCC7_GET)
- return gg_dcc7filedeny((GGPROTO *)proto, hTransfer);
-
- return gg_dccfiledeny((GGPROTO *)proto, hTransfer);
-}
-
-int gg_dccfilecancel(GGPROTO *gg, HANDLE hTransfer)
+int GGPROTO::dccfilecancel(HANDLE hTransfer)
{
struct gg_dcc *dcc = (struct gg_dcc *) hTransfer;
// Remove transfer from any list
- EnterCriticalSection(&gg->ft_mutex);
- if(gg->watches) list_remove(&gg->watches, dcc, 0);
- if(gg->requests) list_remove(&gg->requests, dcc, 0);
- if(gg->transfers) list_remove(&gg->transfers, dcc, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ if (watches) list_remove(&watches, dcc, 0);
+ if (requests) list_remove(&requests, dcc, 0);
+ if (transfers) list_remove(&transfers, dcc, 0);
+ LeaveCriticalSection(&ft_mutex);
// Send failed info
- ProtoBroadcastAck(GG_PROTO, dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc, 0);
// Close file
- if(dcc->file_fd != -1)
+ if (dcc->file_fd != -1)
{
_close(dcc->file_fd);
dcc->file_fd = -1;
}
- gg_netlog(gg, "gg_dccfilecancel(): Canceled file \"%s\" from/to %d.", dcc->file_info.filename, dcc->peer_uin);
+ netlog("gg_dccfilecancel(): Canceled file \"%s\" from/to %d.", dcc->file_info.filename, dcc->peer_uin);
// Free transfer
gg_free_dcc(dcc);
@@ -935,7 +787,7 @@ int gg_dccfilecancel(GGPROTO *gg, HANDLE hTransfer)
return 0;
}
-int gg_dcc7filecancel(GGPROTO *gg, HANDLE hTransfer)
+int GGPROTO::dcc7filecancel(HANDLE hTransfer)
{
struct gg_dcc7 *dcc7 = (struct gg_dcc7 *) hTransfer;
@@ -943,21 +795,21 @@ int gg_dcc7filecancel(GGPROTO *gg, HANDLE hTransfer)
gg_dcc7_abort(dcc7);
// Remove transfer from any list
- EnterCriticalSection(&gg->ft_mutex);
- if(gg->watches) list_remove(&gg->watches, dcc7, 0);
- if(gg->transfers) list_remove(&gg->transfers, dcc7, 0);
- LeaveCriticalSection(&gg->ft_mutex);
+ EnterCriticalSection(&ft_mutex);
+ if (watches) list_remove(&watches, dcc7, 0);
+ if (transfers) list_remove(&transfers, dcc7, 0);
+ LeaveCriticalSection(&ft_mutex);
// Send failed info
- ProtoBroadcastAck(GG_PROTO, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
+ ProtoBroadcastAck(m_szModuleName, dcc7->contact, ACKTYPE_FILE, ACKRESULT_FAILED, dcc7, 0);
// Close file
- if(dcc7->file_fd != -1)
+ if (dcc7->file_fd != -1)
{
_close(dcc7->file_fd);
dcc7->file_fd = -1;
}
- gg_netlog(gg, "gg_dcc7filecancel(): Canceled file \"%s\" from/to %d.", dcc7->filename, dcc7->peer_uin);
+ netlog("gg_dcc7filecancel(): Canceled file \"%s\" from/to %d.", dcc7->filename, dcc7->peer_uin);
// Free transfer
gg_dcc7_free(dcc7);
@@ -966,17 +818,170 @@ int gg_dcc7filecancel(GGPROTO *gg, HANDLE hTransfer)
}
////////////////////////////////////////////////////////////
-// File transfer canceled
-int gg_filecancel(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hTransfer)
+// File receiving allowed
+
+HANDLE GGPROTO::FileAllow(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath)
{
- GGPROTO *gg = (GGPROTO *) proto;
+ // Check if its proper dcc
struct gg_common *c = (struct gg_common *) hTransfer;
+ if (!c)
+ return NULL;
+
+ if (c->type == GG_SESSION_DCC7_GET)
+ return dcc7fileallow(hTransfer, szPath);
+
+ return dccfileallow(hTransfer, szPath);
+}
+
+////////////////////////////////////////////////////////////
+// File transfer canceled
+int GGPROTO::FileCancel(HANDLE hContact, HANDLE hTransfer)
+{
// Check if its proper dcc
- if (!c) return 0;
+ struct gg_common *c = (struct gg_common *) hTransfer;
+ if (!c)
+ return 0;
if (c->type == GG_SESSION_DCC7_SEND || c->type == GG_SESSION_DCC7_GET)
- return gg_dcc7filecancel((GGPROTO *) proto, hTransfer);
+ return dcc7filecancel(hTransfer);
+
+ return dccfilecancel(hTransfer);
+}
+
+////////////////////////////////////////////////////////////
+// File receiving denied
+
+int GGPROTO::FileDeny(HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason)
+{
+ // Check if its proper dcc
+ struct gg_common *c = (struct gg_common *) hTransfer;
+ if (!c)
+ return 0;
+
+ if (c->type == GG_SESSION_DCC7_GET)
+ return dcc7filedeny(hTransfer);
+
+ return dccfiledeny(hTransfer);
+}
+
+////////////////////////////////////////////////////////////
+// Called when received an file
+
+int GGPROTO::RecvFile(HANDLE hContact, PROTOFILEEVENT* pre)
+{
+ CCSDATA ccs = { hContact, PSR_FILE, 0, ( LPARAM )pre };
+ return CallService( MS_PROTO_RECVFILE, 0, ( LPARAM )&ccs );
+}
+
+////////////////////////////////////////////////////////////
+// Called when user sends a file
+
+HANDLE GGPROTO::SendFile(HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles)
+{
+ char *bslash, *filename;
+ struct gg_dcc *dcc;
+ DWORD ip, ver;
+ WORD port;
+ uin_t myuin, uin;
+
+ // Check if main dcc thread is on
+ if (!isonline())
+ return ftfail(this, hContact);
+
+ filename = mir_t2a(ppszFiles[0]);
+
+ // Read user IP and port
+ ip = swap32(db_get_b(hContact, m_szModuleName, GG_KEY_CLIENTIP, 0));
+ port = db_get_w(hContact, m_szModuleName, GG_KEY_CLIENTPORT, 0);
+ myuin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0);
+ uin = db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0);
+ ver = db_get_b(hContact, m_szModuleName, GG_KEY_CLIENTVERSION, 0);
+
+ // Use DCC7 if a contact is using at least version 7.6 or unknown version
+ if ((ver & 0x00ffffff) >= 0x29 || !ver) {
+ struct gg_dcc7 *dcc7;
+
+ EnterCriticalSection(&sess_mutex);
+ if (!(dcc7 = gg_dcc7_send_file(sess, uin, filename, NULL, NULL))) {
+ LeaveCriticalSection(&sess_mutex);
+ netlog("gg_sendfile(): Failed to send file \"%s\".", filename);
+ mir_free(filename);
+ return ftfail(this, hContact);
+ }
+ LeaveCriticalSection(&sess_mutex);
- return gg_dccfilecancel((GGPROTO *) proto, hTransfer);
+ netlog("gg_sendfile(): Sending file \"%s\" to %d.", filename, uin);
+
+ // Add dcc to watches
+ list_add(&watches, dcc7, 0);
+
+ // Store handle
+ dcc7->contact = hContact;
+ dcc7->folder = _strdup(filename);
+ dcc7->tick = 0;
+ // Make folder name
+ bslash = strrchr(dcc7->folder, '\\');
+ if (bslash)
+ *(bslash + 1) = 0;
+ else
+ *(dcc7->folder) = 0;
+ mir_free(filename);
+ return dcc7;
+ }
+
+ // Return if bad connection info
+ if (!port || !uin || !myuin)
+ {
+ netlog("gg_sendfile(): Bad contact uin or my uin. Exit.");
+ mir_free(filename);
+ return ftfail(this, hContact);
+ }
+
+ // Try to connect if not ask user to connect me
+ if ((ip && port >= 10 && !(dcc = gg_dcc_send_file(ip, port, myuin, uin))) || (port < 10 && port > 0))
+ {
+ // Make fake dcc structure
+ dcc = (gg_dcc*)malloc(sizeof(struct gg_dcc));
+ memset(dcc, 0, sizeof(struct gg_dcc));
+ // Fill up structures
+ dcc->uin = myuin;
+ dcc->peer_uin = uin;
+ dcc->fd = -1;
+ dcc->type = GG_SESSION_DCC_SEND;
+ netlog("gg_sendfile(): Requesting user to connect us and scheduling gg_dcc struct for a later use.");
+ EnterCriticalSection(&sess_mutex);
+ gg_dcc_request(sess, uin);
+ LeaveCriticalSection(&sess_mutex);
+ list_add(&requests, dcc, 0);
+ }
+
+ // Write filename
+ if (gg_dcc_fill_file_info(dcc, filename) == -1)
+ {
+ netlog("gg_sendfile(): Cannot open and file fileinfo \"%s\".", filename);
+ gg_free_dcc(dcc);
+ mir_free(filename);
+ return ftfail(this, hContact);
+ }
+
+ netlog("gg_sendfile(): Sending file \"%s\" to %d in %s mode.", filename, uin, (dcc->fd != -1) ? "active" : "passive");
+
+ // Add dcc to watches if not passive
+ if (dcc->fd != -1) list_add(&watches, dcc, 0);
+
+ // Store handle
+ dcc->contact = hContact;
+ dcc->folder = _strdup(filename);
+ dcc->tick = 0;
+ // Make folder name
+ bslash = strrchr(dcc->folder, '\\');
+ if (bslash)
+ *(bslash + 1) = 0;
+ else
+ *(dcc->folder) = 0;
+
+ mir_free(filename);
+ return dcc;
}
+
diff --git a/protocols/Gadu-Gadu/gg.c b/protocols/Gadu-Gadu/gg.cpp
index 74ae376a1f..023d620f1a 100644
--- a/protocols/Gadu-Gadu/gg.c
+++ b/protocols/Gadu-Gadu/gg.cpp
@@ -56,27 +56,25 @@ static unsigned long crc_table[256];
//////////////////////////////////////////////////////////
// Extra winsock function for error description
-char *ws_strerror(int code)
+
+TCHAR* ws_strerror(int code)
{
- static char err_desc[160];
+ static TCHAR err_desc[160];
// Not a windows error display WinSock
- if(code == 0)
+ if (code == 0)
{
- char buff[128];
- int len;
- len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, WSAGetLastError(), 0, buff,
- sizeof(buff), NULL);
- if(len == 0)
- mir_snprintf(err_desc, sizeof(err_desc), "WinSock %u: Unknown error.", WSAGetLastError());
+ TCHAR buff[128];
+ int len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, WSAGetLastError(), 0, buff, SIZEOF(buff), NULL);
+ if (len == 0)
+ mir_sntprintf(err_desc, SIZEOF(err_desc), _T("WinSock %u: Unknown error."), WSAGetLastError());
else
- mir_snprintf(err_desc, sizeof(err_desc), "WinSock %d: %s", WSAGetLastError(), buff);
+ mir_sntprintf(err_desc, SIZEOF(err_desc), _T("WinSock %d: %s"), WSAGetLastError(), buff);
return err_desc;
}
// Return normal error
- return strerror(code);
+ return _tcserror(code);
}
//////////////////////////////////////////////////////////
@@ -137,85 +135,72 @@ const char *http_error_string(int h)
//////////////////////////////////////////////////////////
// Gets plugin info
-__declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
+
+extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
{
return &pluginInfo;
}
-__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
{
return interfaces;
}
//////////////////////////////////////////////////////////
// Cleanups from last plugin
-void gg_cleanuplastplugin(GGPROTO *gg, DWORD version)
+
+void GGPROTO::cleanuplastplugin(DWORD version)
{
HANDLE hContact;
char *szProto;
// Remove bad e-mail and phones from
- if(version < PLUGIN_MAKE_VERSION(0, 0, 1, 4))
+ if (version < PLUGIN_MAKE_VERSION(0, 0, 1, 4))
{
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_cleanuplastplugin(%d): Cleaning junk Phone settings from < 0.0.1.4 ...", version);
+ netlog("gg_cleanuplastplugin(%d): Cleaning junk Phone settings from < 0.0.1.4 ...", version);
#endif
// Look for contact in DB
hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
while (hContact)
{
szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if(szProto != NULL && !strcmp(szProto, GG_PROTO))
+ if (szProto != NULL && !strcmp(szProto, m_szModuleName))
{
// Do contact cleanup
- DBDeleteContactSetting(hContact, GG_PROTO, GG_KEY_EMAIL);
- DBDeleteContactSetting(hContact, GG_PROTO, "Phone");
+ db_unset(hContact, m_szModuleName, GG_KEY_EMAIL);
+ db_unset(hContact, m_szModuleName, "Phone");
}
hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
}
}
// Remove GG entries for non GG contacts
- if(version < PLUGIN_MAKE_VERSION(0, 0, 3, 5))
+ if (version < PLUGIN_MAKE_VERSION(0, 0, 3, 5))
{
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_cleanuplastplugin(%d): Cleaning junk Nick settings from < 0.0.3.5 ...", version);
+ netlog("gg_cleanuplastplugin(%d): Cleaning junk Nick settings from < 0.0.3.5 ...", version);
#endif
// Look for contact in DB
hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
while (hContact)
{
szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if(szProto != NULL && strcmp(szProto, GG_PROTO))
+ if (szProto != NULL && strcmp(szProto, m_szModuleName))
{
// Do nick entry cleanup
- DBDeleteContactSetting(hContact, GG_PROTO, GG_KEY_NICK);
+ db_unset(hContact, m_szModuleName, GG_KEY_NICK);
}
hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
}
}
// Remove old unneeded entry
- if(version < PLUGIN_MAKE_VERSION(0, 0, 5, 3))
- DBDeleteContactSetting(NULL, GG_PROTO, "ShowNotOnMyList");
+ if (version < PLUGIN_MAKE_VERSION(0, 0, 5, 3))
+ db_unset(NULL, m_szModuleName, "ShowNotOnMyList");
// Store this plugin version
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_PLUGINVERSION, pluginInfo.version);
-}
-
-//////////////////////////////////////////////////////////
-// Custom folders initialization
-void gg_initcustomfolders(GGPROTO *gg)
-{
- char szPath[MAX_PATH];
- char *tmpPath = Utils_ReplaceVars("%miranda_avatarcache%");
- mir_snprintf(szPath, MAX_PATH, "%s\\%s", tmpPath, GG_PROTO);
- mir_free(tmpPath);
- gg->hAvatarsFolder = FoldersRegisterCustomPath(GG_PROTO, "Avatars", szPath);
-
- tmpPath = Utils_ReplaceVars("%miranda_userdata%");
- mir_snprintf(szPath, MAX_PATH, "%s\\%s\\ImageCache", tmpPath, GG_PROTO);
- mir_free(tmpPath);
- gg->hImagesFolder = FoldersRegisterCustomPath(GG_PROTO, "Images", szPath);
+ db_set_w(NULL, m_szModuleName, GG_PLUGINVERSION, pluginInfo.version);
}
//////////////////////////////////////////////////////////
@@ -252,8 +237,8 @@ static GGPROTO* gg_getprotoinstance(HANDLE hContact)
for (; l; l = l->next)
{
- GGPROTO* gg = l->data;
- if (strcmp(szProto, GG_PROTO) == 0)
+ GGPROTO* gg = (GGPROTO*)l->data;
+ if (strcmp(szProto, gg->m_szModuleName) == 0)
return gg;
}
@@ -273,11 +258,11 @@ static int gg_prebuildcontactmenu(WPARAM wParam, LPARAM lParam)
mi.cbSize = sizeof(mi);
mi.flags = CMIM_NAME | CMIM_FLAGS | CMIF_ICONFROMICOLIB;
- if (DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0) == DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0) ||
- DBGetContactSettingByte(hContact, GG_PROTO, "ChatRoom", 0) ||
- DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ if (db_get_b(hContact, gg->m_szModuleName, GG_KEY_UIN, 0) == db_get_b(NULL, gg->m_szModuleName, GG_KEY_UIN, 0) ||
+ db_get_b(hContact, gg->m_szModuleName, "ChatRoom", 0) ||
+ db_get_b(hContact, "CList", "NotOnList", 0))
mi.flags |= CMIF_HIDDEN;
- mi.pszName = DBGetContactSettingByte(hContact, GG_PROTO, GG_KEY_BLOCK, 0) ? LPGEN("&Unblock") : LPGEN("&Block");
+ mi.pszName = db_get_b(hContact, gg->m_szModuleName, GG_KEY_BLOCK, 0) ? LPGEN("&Unblock") : LPGEN("&Block");
CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)gg->hBlockMenuItem, (LPARAM)&mi);
return 0;
@@ -285,19 +270,20 @@ static int gg_prebuildcontactmenu(WPARAM wParam, LPARAM lParam)
//////////////////////////////////////////////////////////
// Contact block service function
-INT_PTR gg_blockuser(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
+INT_PTR GGPROTO::blockuser(WPARAM wParam, LPARAM lParam)
{
const HANDLE hContact = (HANDLE)wParam;
- DBWriteContactSettingByte(hContact, GG_PROTO, GG_KEY_BLOCK, !DBGetContactSettingByte(hContact, GG_PROTO, GG_KEY_BLOCK, 0));
- gg_notifyuser(gg, hContact, 1);
+ db_set_b(hContact, m_szModuleName, GG_KEY_BLOCK, !db_get_b(hContact, m_szModuleName, GG_KEY_BLOCK, 0));
+ notifyuser(hContact, 1);
return 0;
}
//////////////////////////////////////////////////////////
// Contact blocking initialization
+
#define GGS_BLOCKUSER "%s/BlockUser"
-static void gg_block_init(GGPROTO *gg)
+void GGPROTO::block_init()
{
CLISTMENUITEM mi = {0};
char service[64];
@@ -305,42 +291,43 @@ static void gg_block_init(GGPROTO *gg)
mi.cbSize = sizeof(mi);
mi.flags = CMIF_ICONFROMICOLIB;
- mir_snprintf(service, sizeof(service), GGS_BLOCKUSER, GG_PROTO);
- CreateProtoServiceFunction(service, gg_blockuser, gg);
+ mir_snprintf(service, sizeof(service), GGS_BLOCKUSER, m_szModuleName);
+ createProtoService(service, &GGPROTO::blockuser);
mi.position = -500050000;
mi.icolibItem = GetIconHandle(IDI_BLOCK);
mi.pszName = LPGEN("&Block");
mi.pszService = service;
- mi.pszContactOwner = GG_PROTO;
- gg->hBlockMenuItem = Menu_AddContactMenuItem(&mi);
+ mi.pszContactOwner = m_szModuleName;
+ hBlockMenuItem = Menu_AddContactMenuItem(&mi);
- gg->hPrebuildMenuHook = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, gg_prebuildcontactmenu);
+ hPrebuildMenuHook = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, gg_prebuildcontactmenu);
}
//////////////////////////////////////////////////////////
// Contact blocking uninitialization
-static void gg_block_uninit(GGPROTO *gg)
+
+void GGPROTO::block_uninit()
{
- UnhookEvent(gg->hPrebuildMenuHook);
- CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)gg->hBlockMenuItem, 0);
+ UnhookEvent(hPrebuildMenuHook);
+ CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hBlockMenuItem, 0);
}
//////////////////////////////////////////////////////////
// Menus initialization
-void gg_menus_init(GGPROTO *gg)
+void GGPROTO::menus_init()
{
- HGENMENU hGCRoot, hCLRoot, hRoot = MO_GetProtoRootMenu(gg->proto.m_szModuleName);
+ HGENMENU hGCRoot, hCLRoot, hRoot = MO_GetProtoRootMenu(m_szModuleName);
CLISTMENUITEM mi = {0};
mi.cbSize = sizeof(mi);
if (hRoot == NULL)
{
- mi.ptszName = GG_PROTONAME;
+ mi.ptszName = m_tszUserName;
mi.position = 500090000;
mi.hParentMenu = HGENMENU_ROOT;
mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED;
mi.icolibItem = GetIconHandle(IDI_GG);
- hGCRoot = hCLRoot = hRoot = gg->hMenuRoot = Menu_AddProtoMenuItem(&mi);
+ hGCRoot = hCLRoot = hRoot = hMenuRoot = Menu_AddProtoMenuItem(&mi);
}
else
{
@@ -357,223 +344,45 @@ void gg_menus_init(GGPROTO *gg)
mi.icolibItem = GetIconHandle(IDI_LIST);
hCLRoot = Menu_AddProtoMenuItem(&mi);
- if (gg->hMenuRoot)
- CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)gg->hMenuRoot, 0);
- gg->hMenuRoot = NULL;
+ if (hMenuRoot)
+ CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)hMenuRoot, 0);
+ hMenuRoot = NULL;
}
- gg_gc_menus_init(gg, hGCRoot);
- gg_import_init(gg, hCLRoot);
- gg_sessions_menus_init(gg, hRoot);
-}
-
-//////////////////////////////////////////////////////////
-// Custom protocol event
-int gg_event(PROTO_INTERFACE *proto, PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- switch( eventType )
- {
- case EV_PROTO_ONLOAD:
- {
- gg->hookOptsInit = HookProtoEvent(ME_OPT_INITIALISE, gg_options_init, gg);
- gg->hookUserInfoInit = HookProtoEvent(ME_USERINFO_INITIALISE, gg_details_init, gg);
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_event(EV_PROTO_ONLOAD): loading modules...");
-#endif
- // Init misc stuff
- gg_icolib_init();
- gg_initpopups(gg);
- gg_gc_init(gg);
- gg_keepalive_init(gg);
- gg_img_init(gg);
- gg_block_init(gg);
-
- // Try to fetch user avatar
- gg_getuseravatar(gg);
- break;
- }
- case EV_PROTO_ONEXIT:
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_event(EV_PROTO_ONEXIT)/gg_preshutdown(): signalling shutdown...");
-#endif
- // Stop avatar request thread
- gg_uninitavatarrequestthread(gg);
- // Stop main connection session thread
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_event(EV_PROTO_ONEXIT): Waiting until Server Thread finished, if needed.");
-#endif
- gg_threadwait(gg, &gg->pth_sess);
- gg_img_shutdown(gg);
- gg_sessions_closedlg(gg);
- break;
-
- case EV_PROTO_ONOPTIONS:
- return gg_options_init(gg, wParam, lParam);
-
- case EV_PROTO_ONMENU:
- gg_menus_init(gg);
- break;
-
- case EV_PROTO_ONRENAME:
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_event(EV_PROTO_ONRENAME): renaming account...");
-#endif
- mir_free(gg->name);
- gg->name = gg_t2a(gg->proto.m_tszUserName);
- if (gg->hMenuRoot)
- {
- CLISTMENUITEM mi = {0};
- mi.cbSize = sizeof(mi);
- mi.flags = CMIM_NAME | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED;
- mi.ptszName = GG_PROTONAME;
- CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)gg->hMenuRoot, (LPARAM)&mi);
- }
- break;
-
- case EV_PROTO_ONCONTACTDELETED:
- return gg_contactdeleted(gg, wParam, lParam);
-
- case EV_PROTO_DBSETTINGSCHANGED:
- return gg_dbsettingchanged(gg, wParam, lParam);
- }
- return TRUE;
+ gc_menus_init(hGCRoot);
+ import_init(hCLRoot);
+ sessions_menus_init(hRoot);
}
//////////////////////////////////////////////////////////
// Module instance initialization
+
static GGPROTO *gg_proto_init(const char* pszProtoName, const TCHAR* tszUserName)
{
- DWORD dwVersion;
- GGPROTO *gg = (GGPROTO *)mir_alloc(sizeof(GGPROTO));
- char szVer[MAX_PATH];
- char name[128];
- NETLIBUSER nlu = { 0 };
-
- ZeroMemory(gg, sizeof(GGPROTO));
- gg->proto.vtbl = (PROTO_INTERFACE_VTBL*)mir_alloc(sizeof(PROTO_INTERFACE_VTBL));
- // Are we running under unicode Miranda core ?
- CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer);
- _strlwr(szVer); // make sure it is lowercase
- gg->unicode_core = (strstr(szVer, "unicode") != NULL);
-
- // Init mutexes
- InitializeCriticalSection(&gg->sess_mutex);
- InitializeCriticalSection(&gg->ft_mutex);
- InitializeCriticalSection(&gg->img_mutex);
- InitializeCriticalSection(&gg->modemsg_mutex);
- InitializeCriticalSection(&gg->avatar_mutex);
- InitializeCriticalSection(&gg->sessions_mutex);
-
- // Init instance names
- gg->proto.m_szModuleName = mir_strdup(pszProtoName);
- gg->proto.m_szProtoName = GGDEF_PROTONAME;
- gg->proto.m_iVersion = 2;
-
-/* Anyway we won't get Unicode in GG yet */
-#ifdef _UNICODE
- gg->name = gg->proto.m_tszUserName = mir_tstrdup(tszUserName);
-#else
- gg->proto.m_tszUserName = gg->unicode_core ? (TCHAR *)mir_wstrdup((wchar_t *)tszUserName) : (TCHAR *)mir_strdup((char *)tszUserName);
- gg->name = gg_t2a(tszUserName);
-#endif
-
- // Register netlib user
- nlu.cbSize = sizeof(nlu);
- nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS;
- nlu.szSettingsModule = gg->proto.m_szModuleName;
- mir_snprintf(name, SIZEOF(name), Translate("%s connection"), gg->proto.m_tszUserName);
- nlu.ptszDescriptiveName = name;
-
- gg->netlib = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
-
- // Register services
- gg_registerservices(gg);
-
- // Offline contacts and clear logon time
- gg_setalloffline(gg);
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_KEY_LOGONTIME, 0);
-
- if ((dwVersion = DBGetContactSettingDword(NULL, GG_PROTO, GG_PLUGINVERSION, 0)) < pluginInfo.version)
- gg_cleanuplastplugin(gg, dwVersion);
-
- // Add to the instance list
+ GGPROTO *gg = new GGPROTO(pszProtoName, tszUserName);
list_add(&g_Instances, gg, 0);
-
- gg_links_instance_init(gg);
- gg_initcustomfolders(gg);
- gg_initavatarrequestthread(gg);
-
return gg;
}
//////////////////////////////////////////////////////////
// Module instance uninitialization
+
static int gg_proto_uninit(PROTO_INTERFACE *proto)
{
GGPROTO *gg = (GGPROTO *)proto;
-
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_proto_uninit(): destroying protocol interface");
-#endif
-
- // Destroy modules
- gg_block_uninit(gg);
- gg_img_destroy(gg);
- gg_keepalive_destroy(gg);
- gg_gc_destroy(gg);
-
- // Remove from the instance list
list_remove(&g_Instances, gg, 0);
-
- if (gg->hMenuRoot)
- CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)gg->hMenuRoot, 0);
-
- // Close handles
- LocalEventUnhook(gg->hookOptsInit);
- LocalEventUnhook(gg->hookUserInfoInit);
- Netlib_CloseHandle(gg->netlib);
-
- // Destroy mutexes
- DeleteCriticalSection(&gg->sess_mutex);
- DeleteCriticalSection(&gg->ft_mutex);
- DeleteCriticalSection(&gg->img_mutex);
- DeleteCriticalSection(&gg->modemsg_mutex);
- DeleteCriticalSection(&gg->avatar_mutex);
- DeleteCriticalSection(&gg->sessions_mutex);
-
- // Free status messages
- if (gg->modemsg.online) mir_free(gg->modemsg.online);
- if (gg->modemsg.away) mir_free(gg->modemsg.away);
- if (gg->modemsg.dnd) mir_free(gg->modemsg.dnd);
- if (gg->modemsg.freechat) mir_free(gg->modemsg.freechat);
- if (gg->modemsg.invisible) mir_free(gg->modemsg.invisible);
- if (gg->modemsg.offline) mir_free(gg->modemsg.offline);
-
- mir_free(gg->proto.m_szModuleName);
- mir_free(gg->proto.m_tszUserName);
- mir_free(gg->name);
- mir_free(gg->proto.vtbl);
- mir_free(gg);
-
+ delete gg;
return 0;
}
//////////////////////////////////////////////////////////
// When plugin is loaded
-int __declspec(dllexport) Load(void)
-{
- WSADATA wsaData;
- PROTOCOLDESCRIPTOR pd;
-
+extern "C" int __declspec(dllexport) Load(void)
+{
mir_getXI(&xi);
mir_getLP(&pluginInfo);
- // Init winsock
- if (WSAStartup(MAKEWORD( 1, 1 ), &wsaData))
- return 1;
-
pcli = (CLIST_INTERFACE*)CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, (LPARAM)hInstance);
// Hook system events
@@ -581,7 +390,7 @@ int __declspec(dllexport) Load(void)
hHookPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, gg_preshutdown);
// Prepare protocol name
- ZeroMemory(&pd, sizeof(pd));
+ PROTOCOLDESCRIPTOR pd = { 0 };
pd.cbSize = sizeof(pd);
pd.szName = GGDEF_PROTO;
pd.fnInit = (pfnInitProto)gg_proto_init;
@@ -600,51 +409,18 @@ int __declspec(dllexport) Load(void)
//////////////////////////////////////////////////////////
// When plugin is unloaded
-int __declspec(dllexport) Unload()
+
+extern "C" int __declspec(dllexport) Unload()
{
LocalEventUnhook(hHookModulesLoaded);
LocalEventUnhook(hHookPreShutdown);
// Cleanup WinSock
WSACleanup();
-
return 0;
}
//////////////////////////////////////////////////////////
-// Adds a new protocol specific service function
-void CreateProtoService(const char* szService, GGPROTOFUNC serviceProc, GGPROTO *gg)
-{
- char str[MAXMODULELABELLENGTH];
- mir_snprintf(str, sizeof(str), "%s%s", gg->proto.m_szModuleName, szService);
- CreateServiceFunctionObj(str, (MIRANDASERVICEOBJ)serviceProc, gg);
-}
-
-//////////////////////////////////////////////////////////
-// Forks a thread
-void gg_forkthread(GGPROTO *gg, GGThreadFunc pFunc, void *param)
-{
- CloseHandle((HANDLE)mir_forkthreadowner((pThreadFuncOwner)&pFunc, gg, param, NULL));
-}
-
-//////////////////////////////////////////////////////////
-// Forks a thread and returns a pseudo handle for it
-HANDLE gg_forkthreadex(GGPROTO *gg, GGThreadFunc pFunc, void *param, UINT *threadId)
-{
- return (HANDLE)mir_forkthreadowner((pThreadFuncOwner)&pFunc, gg, param, threadId);
-}
-
-//////////////////////////////////////////////////////////
-// Wait for thread to stop
-void gg_threadwait(GGPROTO *gg, GGTHREAD *thread)
-{
- if (!thread->hThread) return;
- while (WaitForSingleObjectEx(thread->hThread, INFINITE, TRUE) != WAIT_OBJECT_0);
- CloseHandle(thread->hThread);
- ZeroMemory(thread, sizeof(GGTHREAD));
-}
-
-//////////////////////////////////////////////////////////
// DEBUGING FUNCTIONS
struct
{
@@ -698,11 +474,11 @@ static const ggdebug_eventype2string[] =
{-1, "<unknown event>"}
};
-const char *ggdebug_eventtype(struct gg_event *e)
+const char *ggdebug_eventtype(gg_event *e)
{
int i;
for(i = 0; ggdebug_eventype2string[i].type != -1; i++)
- if(ggdebug_eventype2string[i].type == e->type)
+ if (ggdebug_eventype2string[i].type == e->type)
return ggdebug_eventype2string[i].text;
return ggdebug_eventype2string[i].text;
}
@@ -713,7 +489,7 @@ void gg_debughandler(int level, const char *format, va_list ap)
char szText[1024], *szFormat = _strdup(format);
// Kill end line
char *nl = strrchr(szFormat, '\n');
- if(nl) *nl = 0;
+ if (nl) *nl = 0;
strncpy(szText, "[libgadu] \0", sizeof(szText));
@@ -725,7 +501,8 @@ void gg_debughandler(int level, const char *format, va_list ap)
//////////////////////////////////////////////////////////
// Log funcion
-int gg_netlog(const GGPROTO *gg, const char *fmt, ...)
+
+int GGPROTO::netlog(const char *fmt, ...)
{
va_list va;
char szText[1024];
@@ -733,11 +510,12 @@ int gg_netlog(const GGPROTO *gg, const char *fmt, ...)
va_start(va, fmt);
mir_vsnprintf(szText, sizeof(szText), fmt, va);
va_end(va);
- return CallService(MS_NETLIB_LOG, (WPARAM) gg->netlib, (LPARAM) szText);
+ return CallService(MS_NETLIB_LOG, (WPARAM)netlib, (LPARAM) szText);
}
//////////////////////////////////////////////////////////
// main DLL function
+
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
crc_gentable();
diff --git a/protocols/Gadu-Gadu/gg.h b/protocols/Gadu-Gadu/gg.h
index 7f247c553f..2b1157092b 100644
--- a/protocols/Gadu-Gadu/gg.h
+++ b/protocols/Gadu-Gadu/gg.h
@@ -34,10 +34,6 @@
#include <m_stdhdr.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Windows headers
// Visual C++ .NET tries to include winsock.h
// which is very ver bad
@@ -56,6 +52,7 @@ extern "C" {
// Miranda IM headers
#include <newpluginapi.h>
#include <m_system.h>
+#include <m_system_cpp.h>
#include <m_database.h>
#include <m_netlib.h>
#include <m_protocols.h>
@@ -101,77 +98,26 @@ extern "C" {
#include "resource.h"
// libgadu headers
+extern "C" {
#include "libgadu/libgadu.h"
#include "dynstuff.h"
+};
// Search
// Extended search result structure, used for all searches
-typedef struct
+struct GGSEARCHRESULT : public PROTOSEARCHRESULT
{
- PROTOSEARCHRESULT hdr;
uin_t uin;
-} GGSEARCHRESULT;
+};
typedef struct
{
HANDLE hThread;
- DWORD dwThreadId;
+ UINT dwThreadId;
} GGTHREAD;
typedef struct
{
- PROTO_INTERFACE proto;
- LPTSTR name;
- CRITICAL_SECTION ft_mutex, sess_mutex, img_mutex, modemsg_mutex, avatar_mutex, sessions_mutex;
- list_t watches, transfers, requests, chats, imagedlgs, avatar_requests, avatar_transfers, sessions;
- int gc_enabled, gc_id, list_remove, unicode_core, check_first_conn;
- uin_t next_uin;
- unsigned long last_crc;
- GGTHREAD pth_dcc;
- GGTHREAD pth_sess;
- GGTHREAD pth_avatar;
- struct gg_session *sess;
- struct gg_dcc *dcc;
- HANDLE event;
- HANDLE hConnStopEvent;
- SOCKET sock;
- UINT_PTR timer;
- struct
- {
- char *online;
- char *away;
- char *dnd;
- char *freechat;
- char *invisible;
- char *offline;
- } modemsg;
- HANDLE netlib,
- hookOptsInit,
- hookUserInfoInit,
- hookGCUserEvent,
- hookGCMenuBuild;
- HGENMENU hMenuRoot;
- HGENMENU hMainMenu[7];
- HANDLE hPrebuildMenuHook;
- HANDLE hBlockMenuItem;
- HANDLE hImageMenuItem;
- HANDLE hInstanceMenuItem;
- HANDLE hAvatarsFolder;
- HANDLE hImagesFolder;
- HANDLE hwndSessionsDlg;
-} GGPROTO;
-
-typedef struct
-{
- int mode;
- uin_t uin;
- char *pass;
- char *email;
- GGPROTO *gg;
-} GGUSERUTILDLGDATA;
-
-typedef struct
-{
uin_t *recipients;
int recipients_count;
char id[32];
@@ -184,18 +130,13 @@ typedef struct
char val[256];
} GGTOKEN;
-// GG Thread Function
-typedef void (__cdecl GGThreadFunc)(void*, void*);
-
#if 0 /* #ifdef DEBUGMODE */
-#define EnterCriticalSection(lpCS) {gg_netlog(gg,"EnterCriticalSection @ %s:%d", __FILE__, __LINE__); EnterCriticalSection(lpCS);}
-#define LeaveCriticalSection(lpCS) {gg_netlog(gg,"LeaveCriticalSection @ %s:%d", __FILE__, __LINE__); LeaveCriticalSection(lpCS);}
+#define EnterCriticalSection(lpCS) {netlog(gg,"EnterCriticalSection @ %s:%d", __FILE__, __LINE__); EnterCriticalSection(lpCS);}
+#define LeaveCriticalSection(lpCS) {netlog(gg,"LeaveCriticalSection @ %s:%d", __FILE__, __LINE__); LeaveCriticalSection(lpCS);}
#endif
// Wrappers of the old interface
-#define GG_PROTO (gg->proto.m_szModuleName)
-#define GG_PROTONAME (gg->name)
#define GGDEF_PROTO "GG" // Default Proto
#define GGDEF_PROTONAME "Gadu-Gadu" // Default ProtoName
@@ -338,7 +279,7 @@ typedef void (__cdecl GGThreadFunc)(void*, void*);
#define GG_POPUP_WARNING 8
#define GG_POPUP_MULTILOGON 16
-#define LocalEventUnhook(hook) if(hook) UnhookEvent(hook)
+#define LocalEventUnhook(hook) if (hook) UnhookEvent(hook)
// Some MSVC compatibility with gcc
#ifdef _MSC_VER
@@ -356,6 +297,7 @@ typedef void (__cdecl GGThreadFunc)(void*, void*);
extern HINSTANCE hInstance;
extern CLIST_INTERFACE *pcli;
extern list_t g_Instances;
+extern PLUGININFOEX pluginInfo;
// Screen saver
#ifndef SPI_GETSCREENSAVERRUNNING
@@ -368,80 +310,14 @@ extern list_t g_Instances;
/* Helper functions */
const char *http_error_string(int h);
unsigned long crc_get(char *mem);
-int status_m2gg(GGPROTO *gg, int status, int descr);
-int status_gg2m(GGPROTO *gg, int status);
+int gg_normalizestatus(int status);
char *gg_status2db(int status, const char *suffix);
-char *ws_strerror(int code);
+TCHAR *ws_strerror(int code);
uint32_t swap32(uint32_t x);
const char *gg_version2string(int v);
-void gg_checknewuser(GGPROTO* gg, uin_t uin, const char* passwd);
-
-/* Thread functions */
-void gg_forkthread(GGPROTO *gg, GGThreadFunc pFunc, void *param);
-HANDLE gg_forkthreadex(GGPROTO *gg, GGThreadFunc pFunc, void *param, UINT *threadId);
-void gg_threadwait(GGPROTO *gg, GGTHREAD *thread);
-
-/* Global GG functions */
-void gg_notifyuser(GGPROTO *gg, HANDLE hContact, int refresh);
-void gg_setalloffline(GGPROTO *gg);
-void gg_disconnect(GGPROTO *gg);
-HANDLE gg_getcontact(GGPROTO *gg, uin_t uin, int create, int inlist, char *nick);
-void gg_registerservices(GGPROTO *gg);
-void __cdecl gg_mainthread(GGPROTO *gg, void *empty);
-int gg_isonline(GGPROTO *gg);
-int gg_refreshstatus(GGPROTO *gg, int status);
-
-void gg_broadcastnewstatus(GGPROTO *gg, int newStatus);
-int gg_contactdeleted(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-int gg_dbsettingchanged(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-void gg_notifyall(GGPROTO *gg);
-void gg_changecontactstatus(GGPROTO *gg, uin_t uin, int status, const char *idescr, int time, uint32_t remote_ip, uint16_t remote_port, uint32_t version);
-char *gg_getstatusmsg(GGPROTO *gg, int status);
-void gg_dccstart(GGPROTO *gg);
-void gg_dccconnect(GGPROTO *gg, uin_t uin);
-int gg_gettoken(GGPROTO *gg, GGTOKEN *token);
-void gg_parsecontacts(GGPROTO *gg, char *contacts);
-int gg_getinfo(PROTO_INTERFACE *proto, HANDLE hContact, int infoType);
-void gg_remindpassword(GGPROTO *gg, uin_t uin, const char *email);
-void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName);
-int gg_img_releasepicture(void *img);
-int gg_img_display(GGPROTO *gg, HANDLE hContact, void *img);
-int gg_img_displayasmsg(GGPROTO *gg, HANDLE hContact, void *img);
-int gg_event(PROTO_INTERFACE *proto, PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam);
/* Avatar functions */
-void gg_getavatarfilename(GGPROTO *gg, HANDLE hContact, char *pszDest, int cbLen);
char *gg_avatarhash(char *param);
-void gg_getavatar(GGPROTO *gg, HANDLE hContact, char *szAvatarURL);
-void gg_requestavatar(GGPROTO *gg, HANDLE hContact, int iWaitFor);
-void gg_initavatarrequestthread(GGPROTO *gg);
-void gg_uninitavatarrequestthread(GGPROTO *gg);
-void gg_getuseravatar(GGPROTO *gg);
-void gg_setavatar(GGPROTO *gg, const char *szFilename);
-INT_PTR gg_getavatarinfo(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-
-/* File transfer functions */
-HANDLE gg_fileallow(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath);
-int gg_filecancel(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hTransfer);
-int gg_filedeny(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason);
-int gg_recvfile(PROTO_INTERFACE *proto, HANDLE hContact, PROTOFILEEVENT* pre);
-HANDLE gg_sendfile(PROTO_INTERFACE *proto, HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles);
-
-/* Import module */
-void gg_import_init(GGPROTO *gg, HGENMENU hRoot);
-
-/* Keep-alive module */
-void gg_keepalive_init(GGPROTO *gg);
-void gg_keepalive_destroy(GGPROTO *gg);
-
-/* Image reception functions */
-int gg_img_init(GGPROTO *gg);
-int gg_img_destroy(GGPROTO *gg);
-int gg_img_shutdown(GGPROTO *gg);
-INT_PTR gg_img_recvimage(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-INT_PTR gg_img_sendimage(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-int gg_img_sendonrequest(GGPROTO *gg, struct gg_event* e);
-BOOL gg_img_opened(GGPROTO *gg, uin_t uin);
/* IcoLib functions */
void gg_icolib_init();
@@ -455,50 +331,12 @@ void WindowFreeIcon(HWND hWnd);
void gg_links_instancemenu_init();
void gg_links_init();
void gg_links_destroy();
-void gg_links_instance_init(GGPROTO* gg);
-
-/* OAuth functions */
-char *gg_oauth_header(GGPROTO *gg, const char *httpmethod, const char *url);
-int gg_oauth_checktoken(GGPROTO *gg, int force);
-
-/* UI page initializers */
-int gg_options_init(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-int gg_details_init(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-
-/* Groupchat functions */
-int gg_gc_init(GGPROTO *gg);
-void gg_gc_menus_init(GGPROTO *gg, HGENMENU hRoot);
-int gg_gc_destroy(GGPROTO *gg);
-char * gg_gc_getchat(GGPROTO *gg, uin_t sender, uin_t *recipients, int recipients_count);
-GGGC *gg_gc_lookup(GGPROTO *gg, char *id);
-int gg_gc_changenick(GGPROTO *gg, HANDLE hContact, char *pszNick);
-#define UIN2ID(uin,id) _itoa(uin,id,10)
-
-/* Popups functions */
-void gg_initpopups(GGPROTO* gg);
-void gg_showpopup(GGPROTO* gg, const char* nickname, const char* msg, int flags);
-/* Sessions functions */
-INT_PTR gg_sessions_view(GGPROTO* gg, WPARAM wParam, LPARAM lParam);
-void gg_sessions_updatedlg(GGPROTO* gg);
-BOOL gg_sessions_closedlg(GGPROTO* gg);
-void gg_sessions_menus_init(GGPROTO* gg, HGENMENU hRoot);
-
-/* Event helpers */
-#define HookProtoEvent(name, func, proto) HookEventObj(name, (MIRANDAHOOKOBJ)func, proto)
-#define CreateProtoServiceFunction(name, func, proto) CreateServiceFunctionObj(name, (MIRANDASERVICEOBJ)func, proto)
-typedef INT_PTR (*GGPROTOFUNC)(GGPROTO*,WPARAM,LPARAM);
-void CreateProtoService(const char* szService, GGPROTOFUNC serviceProc, GGPROTO *gg);
-
-/* ANSI <-> Unicode conversion helpers */
-#define gg_a2t(s) gg->unicode_core ? (TCHAR *)mir_a2u(s) : (TCHAR *)mir_strdup(s)
-#define gg_t2a(s) gg->unicode_core ? mir_u2a((wchar_t *)s) : mir_strdup(s)
+#define UIN2ID(uin,id) _itoa(uin,id,10)
// Debug functions
-int gg_netlog(const GGPROTO *gg, const char *fmt, ...);
-const char *ggdebug_eventtype(struct gg_event *e);
+const char *ggdebug_eventtype(gg_event *e);
+
+#include "gg_proto.h"
-#ifdef __cplusplus
-}
-#endif
#endif
diff --git a/protocols/Gadu-Gadu/groupchat.c b/protocols/Gadu-Gadu/groupchat.cpp
index ddeea1a7cf..31fe5d37e8 100644
--- a/protocols/Gadu-Gadu/groupchat.c
+++ b/protocols/Gadu-Gadu/groupchat.cpp
@@ -25,15 +25,12 @@
#define GGS_OPEN_CONF "%s/OpenConf"
#define GGS_CLEAR_IGNORED "%s/ClearIgnored"
-int gg_gc_event(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-INT_PTR gg_gc_openconf(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-INT_PTR gg_gc_clearignored(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
-
////////////////////////////////////////////////////////////////////////////////
// Inits Gadu-Gadu groupchat module using chat.dll
-int gg_gc_init(GGPROTO *gg)
+
+int GGPROTO::gc_init()
{
- if(ServiceExists(MS_GC_REGISTER))
+ if (ServiceExists(MS_GC_REGISTER))
{
char service[64];
GCREGISTER gcr = {0};
@@ -44,26 +41,27 @@ int gg_gc_init(GGPROTO *gg)
gcr.iMaxText = 0;
gcr.nColors = 0;
gcr.pColors = 0;
- gcr.ptszModuleDispName = gg->proto.m_tszUserName;
- gcr.pszModule = GG_PROTO;
+ gcr.ptszModuleDispName = m_tszUserName;
+ gcr.pszModule = m_szModuleName;
CallServiceSync(MS_GC_REGISTER, 0, (LPARAM)&gcr);
- gg->hookGCUserEvent = HookProtoEvent(ME_GC_EVENT, gg_gc_event, gg);
- gg->gc_enabled = TRUE;
+ hookProtoEvent(ME_GC_EVENT, &GGPROTO::gc_event);
+ gc_enabled = TRUE;
// create & hook event
- mir_snprintf(service, 64, GG_GC_GETCHAT, GG_PROTO);
- gg_netlog(gg, "gg_gc_init(): Registered with groupchat plugin.");
+ mir_snprintf(service, 64, GG_GC_GETCHAT, m_szModuleName);
+ netlog("gg_gc_init(): Registered with groupchat plugin.");
}
else
- gg_netlog(gg, "gg_gc_init(): Cannot register with groupchat plugin !!!");
+ netlog("gg_gc_init(): Cannot register with groupchat plugin !!!");
return 1;
}
////////////////////////////////////////////////////////////////////////////////
// Groupchat menus initialization
-void gg_gc_menus_init(GGPROTO *gg, HGENMENU hRoot)
+
+void GGPROTO::gc_menus_init(HGENMENU hRoot)
{
- if(gg->gc_enabled)
+ if (gc_enabled)
{
CLISTMENUITEM mi = {0};
char service[64];
@@ -73,58 +71,56 @@ void gg_gc_menus_init(GGPROTO *gg, HGENMENU hRoot)
mi.hParentMenu = hRoot;
// Conferencing
- mir_snprintf(service, sizeof(service), GGS_OPEN_CONF, GG_PROTO);
- CreateProtoServiceFunction(service, gg_gc_openconf, gg);
+ mir_snprintf(service, sizeof(service), GGS_OPEN_CONF, m_szModuleName);
+ createProtoService(service, &GGPROTO::gc_openconf);
mi.position = 2000050001;
mi.icolibItem = GetIconHandle(IDI_CONFERENCE);
mi.pszName = LPGEN("Open &conference...");
mi.pszService = service;
- gg->hMainMenu[0] = Menu_AddProtoMenuItem(&mi);
+ hMainMenu[0] = Menu_AddProtoMenuItem(&mi);
// Clear ignored conferences
- mir_snprintf(service, sizeof(service), GGS_CLEAR_IGNORED, GG_PROTO);
- CreateProtoServiceFunction(service, gg_gc_clearignored, gg);
+ mir_snprintf(service, sizeof(service), GGS_CLEAR_IGNORED, m_szModuleName);
+ createProtoService(service, &GGPROTO::gc_clearignored);
mi.position = 2000050002;
mi.icolibItem = GetIconHandle(IDI_CLEAR_CONFERENCE);
mi.pszName = LPGEN("&Clear ignored conferences");
mi.pszService = service;
- gg->hMainMenu[1] = Menu_AddProtoMenuItem(&mi);
+ hMainMenu[1] = Menu_AddProtoMenuItem(&mi);
}
}
////////////////////////////////////////////////////////////////////////////////
// Releases Gadu-Gadu groupchat module using chat.dll
-int gg_gc_destroy(GGPROTO *gg)
+
+int GGPROTO::gc_destroy()
{
list_t l;
- for(l = gg->chats; l; l = l->next)
+ for(l = chats; l; l = l->next)
{
GGGC *chat = (GGGC *)l->data;
- if(chat->recipients) free(chat->recipients);
+ if (chat->recipients) free(chat->recipients);
}
- list_destroy(gg->chats, 1); gg->chats = NULL;
- LocalEventUnhook(gg->hookGCUserEvent);
- LocalEventUnhook(gg->hookGCMenuBuild);
-
+ list_destroy(chats, 1); chats = NULL;
return 1;
}
-GGGC *gg_gc_lookup(GGPROTO *gg, char *id)
+GGGC* GGPROTO::gc_lookup(char *id)
{
GGGC *chat;
list_t l;
- for(l = gg->chats; l; l = l->next)
+ for(l = chats; l; l = l->next)
{
chat = (GGGC *)l->data;
- if(chat && !strcmp(chat->id, id))
+ if (chat && !strcmp(chat->id, id))
return chat;
}
return NULL;
}
-int gg_gc_event(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
+int GGPROTO::gc_event(WPARAM wParam, LPARAM lParam)
{
GCHOOK *gch = (GCHOOK *)lParam;
GGGC *chat = NULL;
@@ -135,27 +131,27 @@ int gg_gc_event(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
|| !gch->pDest
|| !gch->pDest->pszID
|| !gch->pDest->pszModule
- || lstrcmpi(gch->pDest->pszModule, GG_PROTO)
- || !(uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
- || !(chat = gg_gc_lookup(gg, gch->pDest->pszID)))
+ || lstrcmpiA(gch->pDest->pszModule, m_szModuleName)
+ || !(uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0))
+ || !(chat = gc_lookup(gch->pDest->pszID)))
return 0;
// Window terminated
- if(gch->pDest->iType == SESSION_TERMINATE)
+ if (gch->pDest->iType == SESSION_TERMINATE)
{
HANDLE hContact = NULL;
- gg_netlog(gg, "gg_gc_event(): Terminating chat %x, id %s from chat window...", chat, gch->pDest->pszID);
+ netlog("gg_gc_event(): Terminating chat %x, id %s from chat window...", chat, gch->pDest->pszID);
// Destroy chat entry
free(chat->recipients);
- list_remove(&gg->chats, chat, 1);
+ list_remove(&chats, chat, 1);
// Remove contact from contact list (duh!) should be done by chat.dll !!
hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
while (hContact)
{
DBVARIANT dbv;
- if (!DBGetContactSettingString(hContact, GG_PROTO, "ChatRoomID", &dbv))
+ if (!db_get_s(hContact, m_szModuleName, "ChatRoomID", &dbv, DBVT_ASCIIZ))
{
- if(dbv.pszVal && !strcmp(gch->pDest->pszID, dbv.pszVal))
+ if (dbv.pszVal && !strcmp(gch->pDest->pszID, dbv.pszVal))
CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0);
DBFreeVariant(&dbv);
}
@@ -165,11 +161,11 @@ int gg_gc_event(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
}
// Message typed / send only if online
- if(gg_isonline(gg) && (gch->pDest->iType == GC_USER_MESSAGE) && gch->pszText)
+ if (isonline() && (gch->pDest->iType == GC_USER_MESSAGE) && gch->pszText)
{
char id[32];
DBVARIANT dbv;
- GCDEST gcdest = {GG_PROTO, gch->pDest->pszID, GC_EVENT_MESSAGE};
+ GCDEST gcdest = {m_szModuleName, gch->pDest->pszID, GC_EVENT_MESSAGE};
GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
int lc;
@@ -177,7 +173,7 @@ int gg_gc_event(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
gcevent.pszUID = id;
gcevent.pszText = gch->pszText;
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_NICK, &dbv))
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_NICK, &dbv, DBVT_ASCIIZ))
gcevent.pszNick = dbv.pszVal;
else
gcevent.pszNick = Translate("Me");
@@ -188,23 +184,23 @@ int gg_gc_event(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
gcevent.time = time(NULL);
gcevent.bIsMe = 1;
gcevent.dwFlags = GCEF_ADDTOLOG;
- gg_netlog(gg, "gg_gc_event(): Sending conference message to room %s, \"%s\".", gch->pDest->pszID, gch->pszText);
+ netlog("gg_gc_event(): Sending conference message to room %s, \"%s\".", gch->pDest->pszID, gch->pszText);
CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
- if(gcevent.pszNick == dbv.pszVal) DBFreeVariant(&dbv);
- EnterCriticalSection(&gg->sess_mutex);
- gg_send_message_confer(gg->sess, GG_CLASS_CHAT, chat->recipients_count, chat->recipients, gch->pszText);
- LeaveCriticalSection(&gg->sess_mutex);
+ if (gcevent.pszNick == dbv.pszVal) DBFreeVariant(&dbv);
+ EnterCriticalSection(&sess_mutex);
+ gg_send_message_confer(sess, GG_CLASS_CHAT, chat->recipients_count, chat->recipients, (BYTE*)gch->pszText);
+ LeaveCriticalSection(&sess_mutex);
return 1;
}
// Privmessage selected
- if(gch->pDest->iType == GC_USER_PRIVMESS)
+ if (gch->pDest->iType == GC_USER_PRIVMESS)
{
HANDLE hContact = NULL;
- if ((uin = atoi(gch->pszUID)) && (hContact = gg_getcontact(gg, uin, 1, 0, NULL)))
+ if ((uin = atoi(gch->pszUID)) && (hContact = getcontact(uin, 1, 0, NULL)))
CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, (LPARAM)0);
}
- gg_netlog(gg, "gg_gc_event(): Unhandled event %d, chat %x, uin %d, text \"%s\".", gch->pDest->iType, chat, uin, gch->pszText);
+ netlog("gg_gc_event(): Unhandled event %d, chat %x, uin %d, text \"%s\".", gch->pDest->iType, chat, uin, gch->pszText);
return 0;
}
@@ -219,45 +215,45 @@ typedef struct _gg_gc_echat
////////////////////////////////////////////////////////////////////////////////
// This is main groupchat initialization routine
-char *gg_gc_getchat(GGPROTO *gg, uin_t sender, uin_t *recipients, int recipients_count)
+
+char* GGPROTO::gc_getchat(uin_t sender, uin_t *recipients, int recipients_count)
{
list_t l; int i;
GGGC *chat;
- char *senderName, status[256], *name, id[32];
+ char id[32];
uin_t uin; DBVARIANT dbv;
- GCSESSION gcwindow;
- GCDEST gcdest = {GG_PROTO, 0, GC_EVENT_ADDGROUP};
+ GCDEST gcdest = {m_szModuleName, 0, GC_EVENT_ADDGROUP};
GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
- gg_netlog(gg, "gg_gc_getchat(): Count %d.", recipients_count);
+ netlog("gg_gc_getchat(): Count %d.", recipients_count);
if (!recipients) return NULL;
// Look for existing chat
- for(l = gg->chats; l; l = l->next)
+ for(l = chats; l; l = l->next)
{
GGGC *chat = (GGGC *)l->data;
if (!chat) continue;
- if(chat->recipients_count == recipients_count + (sender ? 1 : 0))
+ if (chat->recipients_count == recipients_count + (sender ? 1 : 0))
{
int i, j, found = 0, sok = (sender == 0);
if (!sok) for(i = 0; i < chat->recipients_count; i++)
- if(sender == chat->recipients[i])
+ if (sender == chat->recipients[i])
{
sok = 1;
break;
}
- if(sok)
+ if (sok)
for(i = 0; i < chat->recipients_count; i++)
for(j = 0; j < recipients_count; j++)
- if(recipients[j] == chat->recipients[i]) found++;
+ if (recipients[j] == chat->recipients[i]) found++;
// Found all recipients
- if(found == recipients_count)
+ if (found == recipients_count)
{
- if(chat->ignore)
- gg_netlog(gg, "gg_gc_getchat(): Ignoring existing id %s, size %d.", chat->id, chat->recipients_count);
+ if (chat->ignore)
+ netlog("gg_gc_getchat(): Ignoring existing id %s, size %d.", chat->id, chat->recipients_count);
else
- gg_netlog(gg, "gg_gc_getchat(): Returning existing id %s, size %d.", chat->id, chat->recipients_count);
+ netlog("gg_gc_getchat(): Returning existing id %s, size %d.", chat->id, chat->recipients_count);
return !(chat->ignore) ? chat->id : NULL;
}
}
@@ -265,74 +261,71 @@ char *gg_gc_getchat(GGPROTO *gg, uin_t sender, uin_t *recipients, int recipients
// Make new uin list to chat mapping
chat = (GGGC *)malloc(sizeof(GGGC));
- UIN2ID(gg->gc_id ++, chat->id); chat->ignore = FALSE;
+ UIN2ID(gc_id ++, chat->id); chat->ignore = FALSE;
// Check groupchat policy (new) / only for incoming
- if(sender)
+ if (sender)
{
- int unknown = (gg_getcontact(gg, sender, 0, 0, NULL) == NULL),
+ int unknown = (getcontact(sender, 0, 0, NULL) == NULL),
unknownSender = unknown;
for(i = 0; i < recipients_count; i++)
- if (!gg_getcontact(gg, recipients[i], 0, 0, NULL))
+ if (!getcontact(recipients[i], 0, 0, NULL))
unknown ++;
- if ((DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_DEFAULT, GG_KEYDEF_GC_POLICY_DEFAULT) == 2) ||
- (DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_TOTAL, GG_KEYDEF_GC_POLICY_TOTAL) == 2 &&
- recipients_count >= DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_TOTAL, GG_KEYDEF_GC_COUNT_TOTAL)) ||
- (DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_UNKNOWN, GG_KEYDEF_GC_POLICY_UNKNOWN) == 2 &&
- unknown >= DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_UNKNOWN, GG_KEYDEF_GC_COUNT_UNKNOWN)))
+ if ((db_get_w(NULL, m_szModuleName, GG_KEY_GC_POLICY_DEFAULT, GG_KEYDEF_GC_POLICY_DEFAULT) == 2) ||
+ (db_get_w(NULL, m_szModuleName, GG_KEY_GC_POLICY_TOTAL, GG_KEYDEF_GC_POLICY_TOTAL) == 2 &&
+ recipients_count >= db_get_w(NULL, m_szModuleName, GG_KEY_GC_COUNT_TOTAL, GG_KEYDEF_GC_COUNT_TOTAL)) ||
+ (db_get_w(NULL, m_szModuleName, GG_KEY_GC_POLICY_UNKNOWN, GG_KEYDEF_GC_POLICY_UNKNOWN) == 2 &&
+ unknown >= db_get_w(NULL, m_szModuleName, GG_KEY_GC_COUNT_UNKNOWN, GG_KEYDEF_GC_COUNT_UNKNOWN)))
chat->ignore = TRUE;
- if (!chat->ignore && ((DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_DEFAULT, GG_KEYDEF_GC_POLICY_DEFAULT) == 1) ||
- (DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_TOTAL, GG_KEYDEF_GC_POLICY_TOTAL) == 1 &&
- recipients_count >= DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_TOTAL, GG_KEYDEF_GC_COUNT_TOTAL)) ||
- (DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_POLICY_UNKNOWN, GG_KEYDEF_GC_POLICY_UNKNOWN) == 1 &&
- unknown >= DBGetContactSettingWord(NULL, GG_PROTO, GG_KEY_GC_COUNT_UNKNOWN, GG_KEYDEF_GC_COUNT_UNKNOWN))))
+ if (!chat->ignore && ((db_get_w(NULL, m_szModuleName, GG_KEY_GC_POLICY_DEFAULT, GG_KEYDEF_GC_POLICY_DEFAULT) == 1) ||
+ (db_get_w(NULL, m_szModuleName, GG_KEY_GC_POLICY_TOTAL, GG_KEYDEF_GC_POLICY_TOTAL) == 1 &&
+ recipients_count >= db_get_w(NULL, m_szModuleName, GG_KEY_GC_COUNT_TOTAL, GG_KEYDEF_GC_COUNT_TOTAL)) ||
+ (db_get_w(NULL, m_szModuleName, GG_KEY_GC_POLICY_UNKNOWN, GG_KEYDEF_GC_POLICY_UNKNOWN) == 1 &&
+ unknown >= db_get_w(NULL, m_szModuleName, GG_KEY_GC_COUNT_UNKNOWN, GG_KEYDEF_GC_COUNT_UNKNOWN))))
{
- char *senderName = unknownSender ?
- Translate("Unknown") : ((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) gg_getcontact(gg, sender, 0, 0, NULL), 0));
- char error[256];
- mir_snprintf(error, sizeof(error), Translate("%s has initiated conference with %d participants (%d unknowns).\nDo you want do participate ?"),
+ TCHAR *senderName = unknownSender ?
+ TranslateT("Unknown") : pcli->pfnGetContactDisplayName(getcontact(sender, 0, 0, NULL), 0);
+ TCHAR error[256];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("%s has initiated conference with %d participants (%d unknowns).\nDo you want do participate ?"),
senderName, recipients_count + 1, unknown);
- chat->ignore = (MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OKCANCEL | MB_ICONEXCLAMATION
- ) != IDOK);
+ chat->ignore = MessageBox(NULL, error, m_tszUserName, MB_OKCANCEL | MB_ICONEXCLAMATION) != IDOK;
}
- if(chat->ignore)
+ if (chat->ignore)
{
// Copy recipient list
chat->recipients_count = recipients_count + (sender ? 1 : 0);
chat->recipients = (uin_t *)calloc(chat->recipients_count, sizeof(uin_t));
for(i = 0; i < recipients_count; i++)
chat->recipients[i] = recipients[i];
- if(sender) chat->recipients[i] = sender;
- gg_netlog(gg, "gg_gc_getchat(): Ignoring new chat %s, count %d.", chat->id, chat->recipients_count);
- list_add(&gg->chats, chat, 0);
+ if (sender) chat->recipients[i] = sender;
+ netlog("gg_gc_getchat(): Ignoring new chat %s, count %d.", chat->id, chat->recipients_count);
+ list_add(&chats, chat, 0);
return NULL;
}
}
// Create new chat window
- senderName = sender ? (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) gg_getcontact(gg, sender, 1, 0, NULL), 0) : NULL;
- mir_snprintf(status, 255, sender ? Translate("%s initiated the conference.") : Translate("This is my own conference."), senderName);
- gcwindow.cbSize = sizeof(GCSESSION);
- gcwindow.iType = GCW_CHATROOM;
- gcwindow.pszModule = GG_PROTO;
- gcwindow.pszName = sender ? senderName : Translate("Conference");
- gcwindow.pszID = chat->id;
- gcwindow.pszStatusbarText = status;
- gcwindow.dwFlags = 0;
+ TCHAR status[256];
+ TCHAR *senderName = sender ? pcli->pfnGetContactDisplayName(getcontact(sender, 1, 0, NULL), 0) : NULL;
+ mir_sntprintf(status, 255, (sender) ? TranslateT("%s initiated the conference.") : TranslateT("This is my own conference."), senderName);
+ GCSESSION gcwindow = { 0 };
+ gcwindow.cbSize = sizeof(GCSESSION);
+ gcwindow.iType = GCW_CHATROOM;
+ gcwindow.pszModule = m_szModuleName;
+ gcwindow.ptszName = sender ? senderName : TranslateT("Conference");
+ gcwindow.pszID = chat->id;
+ gcwindow.dwFlags = GC_TCHAR;
gcwindow.dwItemData = (DWORD)chat;
+ gcwindow.ptszStatusbarText = status;
// Here we put nice new hash sign
- name = calloc(strlen(gcwindow.pszName) + 2, sizeof(char));
- *name = '#'; strcpy(name + 1, gcwindow.pszName);
- gcwindow.pszName = name;
+ TCHAR *name = (TCHAR*)calloc(_tcslen(gcwindow.ptszName) + 2, sizeof(TCHAR));
+ *name = '#'; _tcscpy(name + 1, gcwindow.ptszName);
+ gcwindow.ptszName = name;
// Create new room
- if(CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM) &gcwindow))
+ if (CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM) &gcwindow))
{
- gg_netlog(gg, "gg_gc_getchat(): Cannot create new chat window %s.", chat->id);
+ netlog("gg_gc_getchat(): Cannot create new chat window %s.", chat->id);
free(name);
free(chat);
return NULL;
@@ -341,55 +334,55 @@ char *gg_gc_getchat(GGPROTO *gg, uin_t sender, uin_t *recipients, int recipients
gcdest.pszID = chat->id;
gcevent.pszUID = id;
- gcevent.dwFlags = GCEF_ADDTOLOG;
+ gcevent.dwFlags = GC_TCHAR | GCEF_ADDTOLOG;
gcevent.time = 0;
// Add normal group
- gcevent.pszStatus = Translate("Participants");
+ gcevent.ptszStatus = TranslateT("Participants");
CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
gcdest.iType = GC_EVENT_JOIN;
// Add myself
- if(uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
+ if (uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0))
{
UIN2ID(uin, id);
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_NICK, &dbv))
- gcevent.pszNick = dbv.pszVal;
- else
- gcevent.pszNick = Translate("Me");
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_NICK, &dbv, DBVT_TCHAR)) {
+ gcevent.ptszNick = NEWTSTR_ALLOCA(dbv.ptszVal);
+ db_free(&dbv);
+ }
+ else gcevent.ptszNick = TranslateT("Me");
gcevent.bIsMe = 1;
CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
- gg_netlog(gg, "gg_gc_getchat(): Myself %s: %s (%s) to the list...", gcevent.pszUID, gcevent.pszNick, gcevent.pszStatus);
- if(gcevent.pszNick == dbv.pszVal) DBFreeVariant(&dbv);
+ netlog("gg_gc_getchat(): Myself %s: %S (%S) to the list...", gcevent.pszUID, gcevent.ptszNick, gcevent.ptszStatus);
}
- else gg_netlog(gg, "gg_gc_getchat(): Myself adding failed with uin %d !!!", uin);
+ else netlog("gg_gc_getchat(): Myself adding failed with uin %d !!!", uin);
// Copy recipient list
chat->recipients_count = recipients_count + (sender ? 1 : 0);
chat->recipients = (uin_t *)calloc(chat->recipients_count, sizeof(uin_t));
for(i = 0; i < recipients_count; i++)
chat->recipients[i] = recipients[i];
- if(sender) chat->recipients[i] = sender;
+ if (sender) chat->recipients[i] = sender;
// Add contacts
- for(i = 0; i < chat->recipients_count; i++)
- {
- HANDLE hContact = gg_getcontact(gg, chat->recipients[i], 1, 0, NULL);
+ for(i = 0; i < chat->recipients_count; i++) {
+ HANDLE hContact = getcontact(chat->recipients[i], 1, 0, NULL);
UIN2ID(chat->recipients[i], id);
- if(hContact && (name = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)))
- gcevent.pszNick = name;
+ if (hContact && (name = pcli->pfnGetContactDisplayName(hContact, 0)) != NULL)
+ gcevent.ptszNick = name;
else
- gcevent.pszNick = Translate("'Unknown'");
+ gcevent.ptszNick = TranslateT("'Unknown'");
gcevent.bIsMe = 0;
- gg_netlog(gg, "gg_gc_getchat(): Added %s: %s (%s) to the list...", gcevent.pszUID, gcevent.pszNick, gcevent.pszStatus);
+ gcevent.dwFlags = GC_TCHAR;
+ netlog("gg_gc_getchat(): Added %s: %S (%S) to the list...", gcevent.pszUID, gcevent.ptszNick, gcevent.pszStatus);
CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gcevent);
}
gcdest.iType = GC_EVENT_CONTROL;
CallServiceSync(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gcevent);
CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gcevent);
- gg_netlog(gg, "gg_gc_getchat(): Returning new chat window %s, count %d.", chat->id, chat->recipients_count);
- list_add(&gg->chats, chat, 0);
+ netlog("gg_gc_getchat(): Returning new chat window %s, count %d.", chat->id, chat->recipients_count);
+ list_add(&chats, chat, 0);
return chat->id;
}
@@ -398,7 +391,7 @@ static HANDLE gg_getsubcontact(GGPROTO* gg, HANDLE hContact)
char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
char* szMetaProto = (char*)CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
- if (szProto && szMetaProto && (INT_PTR)szMetaProto != CALLSERVICE_NOTFOUND && !lstrcmp(szProto, szMetaProto))
+ if (szProto && szMetaProto && (INT_PTR)szMetaProto != CALLSERVICE_NOTFOUND && !lstrcmpA(szProto, szMetaProto))
{
int nSubContacts = (int)CallService(MS_MC_GETNUMCONTACTS, (WPARAM)hContact, 0), i;
HANDLE hMetaContact;
@@ -406,7 +399,7 @@ static HANDLE gg_getsubcontact(GGPROTO* gg, HANDLE hContact)
{
hMetaContact = (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, i);
szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hMetaContact, 0);
- if (szProto && !lstrcmp(szProto, GG_PROTO))
+ if (szProto && !lstrcmpA(szProto, gg->m_szModuleName))
return hMetaContact;
}
}
@@ -472,35 +465,34 @@ static INT_PTR CALLBACK gg_gc_openconfdlg(HWND hwndDlg, UINT message, WPARAM wPa
GGPROTO* gg = (GGPROTO*)GetWindowLongPtr(hwndDlg, DWLP_USER);
int count = 0, i = 0;
// Check if connected
- if (!gg_isonline(gg))
+ if (!gg->isonline())
{
MessageBox(NULL,
- Translate("You have to be connected to open new conference."),
- GG_PROTONAME, MB_OK | MB_ICONSTOP
- );
+ TranslateT("You have to be connected to open new conference."),
+ gg->m_tszUserName, MB_OK | MB_ICONSTOP);
}
else if (hwndList && (count = gg_gc_countcheckmarks(hwndList)) >= 2)
{
// Create new participiants table
char* chat;
- uin_t* participants = calloc(count, sizeof(uin_t));
+ uin_t* participants = (uin_t*)calloc(count, sizeof(uin_t));
HANDLE hItem, hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
- gg_netlog(gg, "gg_gc_getchat(): Opening new conference for %d contacts.", count);
+ gg->netlog("gg_gc_getchat(): Opening new conference for %d contacts.", count);
while (hContact && i < count)
{
hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0);
if (hItem && SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hItem, 0))
{
HANDLE hMetaContact = gg_getsubcontact(gg, hContact); // MetaContacts support
- participants[i++] = DBGetContactSettingDword(hMetaContact ? hMetaContact : hContact, GG_PROTO, GG_KEY_UIN, 0);
+ participants[i++] = db_get_b(hMetaContact ? hMetaContact : hContact, gg->m_szModuleName, GG_KEY_UIN, 0);
}
hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
}
if (count > i) i = count;
- chat = gg_gc_getchat(gg, 0, participants, count);
+ chat = gg->gc_getchat(0, participants, count);
if (chat)
{
- GCDEST gcdest = {GG_PROTO, chat, GC_EVENT_CONTROL};
+ GCDEST gcdest = {gg->m_szModuleName, chat, GC_EVENT_CONTROL};
GCEVENT gcevent = {sizeof(GCEVENT), &gcdest};
CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gcevent);
}
@@ -549,16 +541,16 @@ static INT_PTR CALLBACK gg_gc_openconfdlg(HWND hwndDlg, UINT message, WPARAM wPa
HANDLE hMetaContact = gg_getsubcontact(gg, hContact); // MetaContacts support
if (hMetaContact)
{
- szProto = GG_PROTO;
- uin = (uin_t)DBGetContactSettingDword(hMetaContact, GG_PROTO, GG_KEY_UIN, 0);
+ szProto = gg->m_szModuleName;
+ uin = (uin_t)db_get_b(hMetaContact, gg->m_szModuleName, GG_KEY_UIN, 0);
}
else
{
szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
- uin = (uin_t)DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0);
+ uin = (uin_t)db_get_b(hContact, gg->m_szModuleName, GG_KEY_UIN, 0);
}
- if (szProto == NULL || lstrcmp(szProto, GG_PROTO) || !uin || uin == DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0))
+ if (szProto == NULL || lstrcmpA(szProto, gg->m_szModuleName) || !uin || uin == db_get_b(NULL, gg->m_szModuleName, GG_KEY_UIN, 0))
SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_DELETEITEM, (WPARAM)hItem, 0);
}
hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
@@ -600,64 +592,60 @@ static INT_PTR CALLBACK gg_gc_openconfdlg(HWND hwndDlg, UINT message, WPARAM wPa
return FALSE;
}
-INT_PTR gg_gc_clearignored(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
+INT_PTR GGPROTO::gc_clearignored(WPARAM wParam, LPARAM lParam)
{
- list_t l = gg->chats; BOOL cleared = FALSE;
+ list_t l = chats; BOOL cleared = FALSE;
while(l)
{
GGGC *chat = (GGGC *)l->data;
l = l->next;
- if(chat->ignore)
+ if (chat->ignore)
{
- if(chat->recipients) free(chat->recipients);
- list_remove(&gg->chats, chat, 1);
+ if (chat->recipients) free(chat->recipients);
+ list_remove(&chats, chat, 1);
cleared = TRUE;
}
}
- MessageBox(
- NULL,
+ MessageBox( NULL,
cleared ?
- Translate("All ignored conferences are now unignored and the conference policy will act again.") :
- Translate("There are no ignored conferences."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
+ TranslateT("All ignored conferences are now unignored and the conference policy will act again.") :
+ TranslateT("There are no ignored conferences."),
+ m_tszUserName, MB_OK | MB_ICONINFORMATION
);
return 0;
}
-INT_PTR gg_gc_openconf(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
+INT_PTR GGPROTO::gc_openconf(WPARAM wParam, LPARAM lParam)
{
// Check if connected
- if (!gg_isonline(gg))
+ if (!isonline())
{
MessageBox(NULL,
- Translate("You have to be connected to open new conference."),
- GG_PROTONAME, MB_OK | MB_ICONSTOP
+ TranslateT("You have to be connected to open new conference."),
+ m_tszUserName, MB_OK | MB_ICONSTOP
);
return 0;
}
- CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_CONFERENCE), NULL, gg_gc_openconfdlg, (LPARAM)gg);
+ CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_CONFERENCE), NULL, gg_gc_openconfdlg, (LPARAM)this);
return 1;
}
-int gg_gc_changenick(GGPROTO *gg, HANDLE hContact, char *pszNick)
+int GGPROTO::gc_changenick(HANDLE hContact, char *pszNick)
{
list_t l;
- uin_t uin = DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0);
+ uin_t uin = db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0);
if (!uin || !pszNick) return 0;
- gg_netlog(gg, "gg_gc_changenick(): Nickname for uin %d changed to %s.", uin, pszNick);
+ netlog("gg_gc_changenick(): Nickname for uin %d changed to %s.", uin, pszNick);
// Lookup for chats having this nick
- for(l = gg->chats; l; l = l->next)
- {
- int i;
+ for(l = chats; l; l = l->next) {
GGGC *chat = (GGGC *)l->data;
- if(chat->recipients && chat->recipients_count)
- for(i = 0; i < chat->recipients_count; i++)
+ if (chat->recipients && chat->recipients_count)
+ for(int i = 0; i < chat->recipients_count; i++)
// Rename this window if it's exising in the chat
- if(chat->recipients[i] == uin)
+ if (chat->recipients[i] == uin)
{
char id[32];
GCEVENT gce = {sizeof(GCEVENT)};
@@ -665,12 +653,12 @@ int gg_gc_changenick(GGPROTO *gg, HANDLE hContact, char *pszNick)
UIN2ID(uin, id);
gcd.iType = GC_EVENT_NICK;
- gcd.pszModule = GG_PROTO;
+ gcd.pszModule = m_szModuleName;
gce.pDest = &gcd;
gcd.pszID = chat->id;
gce.pszUID = id;
gce.pszText = pszNick;
- gg_netlog(gg, "gg_gc_changenick(): Found room %s with uin %d, sending nick change %s.", chat->id, uin, id);
+ netlog("gg_gc_changenick(): Found room %s with uin %d, sending nick change %s.", chat->id, uin, id);
CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
break;
diff --git a/protocols/Gadu-Gadu/icolib.c b/protocols/Gadu-Gadu/icolib.cpp
index 58d5c2fe2a..58d5c2fe2a 100644
--- a/protocols/Gadu-Gadu/icolib.c
+++ b/protocols/Gadu-Gadu/icolib.cpp
diff --git a/protocols/Gadu-Gadu/image.c b/protocols/Gadu-Gadu/image.cpp
index a602bf02d8..8cf2db6a2d 100644
--- a/protocols/Gadu-Gadu/image.c
+++ b/protocols/Gadu-Gadu/image.cpp
@@ -40,7 +40,7 @@
typedef struct _GGIMAGEENTRY
{
HBITMAP hBitmap;
- char *lpszFileName;
+ TCHAR *lpszFileName;
char *lpData;
unsigned long nSize;
struct _GGIMAGEENTRY *lpNext;
@@ -62,11 +62,11 @@ typedef struct
// Prototypes
int gg_img_remove(GGIMAGEDLGDATA *dat);
-INT_PTR gg_img_sendimg(GGPROTO *gg, WPARAM wParam, LPARAM lParam);
////////////////////////////////////////////////////////////////////////////
// Image Module : Adding item to contact menu, creating sync objects
-int gg_img_init(GGPROTO *gg)
+
+int GGPROTO::img_init()
{
CLISTMENUITEM mi = {0};
char service[64];
@@ -75,32 +75,32 @@ int gg_img_init(GGPROTO *gg)
mi.flags = CMIF_ICONFROMICOLIB;
// Send image contact menu item
- mir_snprintf(service, sizeof(service), GGS_SENDIMAGE, GG_PROTO);
- CreateProtoServiceFunction(service, gg_img_sendimg, gg);
+ mir_snprintf(service, sizeof(service), GGS_SENDIMAGE, m_szModuleName);
+ createProtoService(service, &GGPROTO::img_sendimg);
mi.position = -2000010000;
mi.icolibItem = GetIconHandle(IDI_IMAGE);
mi.pszName = LPGEN("&Image");
mi.pszService = service;
- mi.pszContactOwner = GG_PROTO;
- gg->hImageMenuItem = Menu_AddContactMenuItem(&mi);
+ mi.pszContactOwner = m_szModuleName;
+ hImageMenuItem = Menu_AddContactMenuItem(&mi);
// Receive image
- mir_snprintf(service, sizeof(service), GGS_RECVIMAGE, GG_PROTO);
- CreateProtoServiceFunction(service, gg_img_recvimage, gg);
+ mir_snprintf(service, sizeof(service), GGS_RECVIMAGE, m_szModuleName);
+ createProtoService(service, &GGPROTO::img_recvimage);
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
// Image Module : closing dialogs, sync objects
-int gg_img_shutdown(GGPROTO *gg)
+int GGPROTO::img_shutdown()
{
list_t l;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_img_shutdown(): Closing all dialogs...");
+ netlog("gg_img_shutdown(): Closing all dialogs...");
#endif
// Rather destroy window instead of just removing structures
- for (l = gg->imagedlgs; l;)
+ for (l = imagedlgs; l;)
{
GGIMAGEDLGDATA *dat = (GGIMAGEDLGDATA *)l->data;
l = l->next;
@@ -111,10 +111,10 @@ int gg_img_shutdown(GGPROTO *gg)
{
// Post message async, since it maybe be different thread
if (!PostMessage(dat->hWnd, WM_CLOSE, 0, 0))
- gg_netlog(gg, "gg_img_shutdown(): Image dlg %x cannot be released !!", dat->hWnd);
+ netlog("gg_img_shutdown(): Image dlg %x cannot be released !!", dat->hWnd);
}
else
- gg_netlog(gg, "gg_img_shutdown(): Image dlg %x not exists, but structure does !!", dat->hWnd);
+ netlog("gg_img_shutdown(): Image dlg %x not exists, but structure does !!", dat->hWnd);
}
}
@@ -123,19 +123,38 @@ int gg_img_shutdown(GGPROTO *gg)
////////////////////////////////////////////////////////////////////////////
// Image Module : destroying list
-int gg_img_destroy(GGPROTO *gg)
+
+int GGPROTO::img_destroy()
{
// Release all dialogs
- while (gg->imagedlgs && gg_img_remove((GGIMAGEDLGDATA *)gg->imagedlgs->data));
+ while (imagedlgs && gg_img_remove((GGIMAGEDLGDATA *)imagedlgs->data));
// Destroy list
- list_destroy(gg->imagedlgs, 1);
- CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)gg->hImageMenuItem, (LPARAM) 0);
+ list_destroy(imagedlgs, 1);
+ CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)hImageMenuItem, (LPARAM) 0);
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
+// Image Window : Frees image entry structure
+
+static int gg_img_releasepicture(void *img)
+{
+ if (!img)
+ return FALSE;
+ if (((GGIMAGEENTRY *)img)->lpszFileName)
+ free(((GGIMAGEENTRY *)img)->lpszFileName);
+ if (((GGIMAGEENTRY *)img)->hBitmap)
+ DeleteObject(((GGIMAGEENTRY *)img)->hBitmap);
+ if (((GGIMAGEENTRY *)img)->lpData)
+ free(((GGIMAGEENTRY *)img)->lpData);
+ free(img);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////
// Painting image
int gg_img_paint(HWND hwnd, GGIMAGEENTRY *dat)
{
@@ -202,21 +221,22 @@ int gg_img_paint(HWND hwnd, GGIMAGEENTRY *dat)
////////////////////////////////////////////////////////////////////////////////
// Returns supported image filters
-char *gg_img_getfilter(char *szFilter, int nSize)
+
+TCHAR *gg_img_getfilter(TCHAR *szFilter, int nSize)
{
- char *szFilterName, *szFilterMask;
- char *pFilter = szFilter;
+ TCHAR *szFilterName, *szFilterMask;
+ TCHAR *pFilter = szFilter;
// Match relative to ImgDecoder presence
- szFilterName = Translate("Image files (*.bmp,*.gif,*.jpeg,*.jpg,*.png)");
- szFilterMask = "*.bmp;*.gif;*.jpeg;*.jpg;*.png";
+ szFilterName = TranslateT("Image files (*.bmp,*.gif,*.jpeg,*.jpg,*.png)");
+ szFilterMask = _T("*.bmp;*.gif;*.jpeg;*.jpg;*.png");
// Make up filter
- strncpy(pFilter, szFilterName, nSize);
- pFilter += strlen(pFilter) + 1;
+ _tcsncpy(pFilter, szFilterName, nSize);
+ pFilter += _tcslen(pFilter) + 1;
if (pFilter >= szFilter + nSize) return NULL;
- strncpy(pFilter, szFilterMask, nSize - (pFilter - szFilter));
- pFilter += strlen(pFilter) + 1;
+ _tcsncpy(pFilter, szFilterMask, nSize - (pFilter - szFilter));
+ pFilter += _tcslen(pFilter) + 1;
if (pFilter >= szFilter + nSize) return NULL;
*pFilter = 0;
@@ -225,16 +245,21 @@ char *gg_img_getfilter(char *szFilter, int nSize)
////////////////////////////////////////////////////////////////////////////////
// Save specified image entry
+
int gg_img_saveimage(HWND hwnd, GGIMAGEENTRY *dat)
{
- OPENFILENAME ofn = {0};
- char szFileName[MAX_PATH];
- char szFilter[128];
+ if (!dat)
+ return FALSE;
- if (!dat) return FALSE;
+ GGPROTO* gg = ((GGIMAGEDLGDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA))->gg;
+
+ TCHAR szFilter[128];
+ gg_img_getfilter(szFilter, SIZEOF(szFilter));
- gg_img_getfilter(szFilter, sizeof(szFilter));
- strncpy(szFileName, dat->lpszFileName, sizeof(szFileName));
+ TCHAR szFileName[MAX_PATH];
+ _tcsncpy(szFileName, dat->lpszFileName, SIZEOF(szFileName));
+
+ OPENFILENAME ofn = {0};
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
ofn.hwndOwner = hwnd;
ofn.hInstance = hInstance;
@@ -244,17 +269,17 @@ int gg_img_saveimage(HWND hwnd, GGIMAGEENTRY *dat)
ofn.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT;
if (GetSaveFileName(&ofn))
{
- FILE *fp = fopen(szFileName, "w+b");
+ FILE *fp = _tfopen(szFileName, _T("w+b"));
if (fp)
{
fwrite(dat->lpData, dat->nSize, 1, fp);
fclose(fp);
- gg_netlog(((GGIMAGEDLGDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA))->gg, "gg_img_saveimage(): Image saved to %s.", szFileName);
+ gg->netlog("gg_img_saveimage(): Image saved to %s.", szFileName);
}
else
{
- gg_netlog(((GGIMAGEDLGDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA))->gg, "gg_img_saveimage(): Cannot save image to %s.", szFileName);
- MessageBox(hwnd, Translate("Image cannot be written to disk."), ((GGIMAGEDLGDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA))->gg->name, MB_OK | MB_ICONERROR);
+ gg->netlog("gg_img_saveimage(): Cannot save image to %s.", szFileName);
+ MessageBox(hwnd, TranslateT("Image cannot be written to disk."), gg->m_tszUserName, MB_OK | MB_ICONERROR);
}
}
@@ -263,6 +288,7 @@ int gg_img_saveimage(HWND hwnd, GGIMAGEENTRY *dat)
////////////////////////////////////////////////////////////////////////////
// Fit window size to image size
+
BOOL gg_img_fit(HWND hwndDlg)
{
GGIMAGEDLGDATA *dat = (GGIMAGEDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
@@ -359,64 +385,62 @@ static INT_PTR CALLBACK gg_img_dlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
{
GGIMAGEDLGDATA *dat = (GGIMAGEDLGDATA *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- char *szName, szTitle[128];
- RECT rect;
-
- TranslateDialogDefault(hwndDlg);
- // This should be already initialized
- // InitCommonControls();
-
- // Get dialog data
- dat = (GGIMAGEDLGDATA *)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
-
- // Save dialog handle
- dat->hWnd = hwndDlg;
-
- // Send event if someone's waiting
- if (dat->hEvent) SetEvent(dat->hEvent);
- else gg_netlog(dat->gg, "gg_img_dlgproc(): Creation event not found, but someone might be waiting.");
-
- // Making buttons flat
- SendDlgItemMessage(hwndDlg, IDC_IMG_PREV, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_IMG_NEXT, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_IMG_DELETE, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_IMG_SAVE, BUTTONSETASFLATBTN, TRUE, 0);
-
- // Setting images for buttons
- SendDlgItemMessage(hwndDlg, IDC_IMG_PREV, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("previous", FALSE));
- SendDlgItemMessage(hwndDlg, IDC_IMG_NEXT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("next", FALSE));
- SendDlgItemMessage(hwndDlg, IDC_IMG_DELETE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("delete", FALSE));
- SendDlgItemMessage(hwndDlg, IDC_IMG_SAVE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("save", FALSE));
-
- // Setting tooltips for buttons
- SendDlgItemMessage(hwndDlg, IDC_IMG_PREV, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Previous image"), BATF_TCHAR);
- SendDlgItemMessage(hwndDlg, IDC_IMG_NEXT, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Next image"), BATF_TCHAR);
- SendDlgItemMessage(hwndDlg, IDC_IMG_DELETE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete image from the list"), BATF_TCHAR);
- SendDlgItemMessage(hwndDlg, IDC_IMG_SAVE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Save image to disk"), BATF_TCHAR);
-
- // Set main window image
- WindowSetIcon(hwndDlg, "image");
-
- szName = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)dat->hContact, 0);
- if (dat->bReceiving)
- mir_snprintf(szTitle, sizeof(szTitle), Translate("Image from %s"), szName);
- else
- mir_snprintf(szTitle, sizeof(szTitle), Translate("Image for %s"), szName);
- SetWindowText(hwndDlg, szTitle);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ RECT rect;
+
+ TranslateDialogDefault(hwndDlg);
+ // This should be already initialized
+ // InitCommonControls();
+
+ // Get dialog data
+ dat = (GGIMAGEDLGDATA *)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+
+ // Save dialog handle
+ dat->hWnd = hwndDlg;
+
+ // Send event if someone's waiting
+ if (dat->hEvent) SetEvent(dat->hEvent);
+ else dat->gg->netlog("gg_img_dlgproc(): Creation event not found, but someone might be waiting.");
+
+ // Making buttons flat
+ SendDlgItemMessage(hwndDlg, IDC_IMG_PREV, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_IMG_NEXT, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_IMG_DELETE, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_IMG_SAVE, BUTTONSETASFLATBTN, TRUE, 0);
+
+ // Setting images for buttons
+ SendDlgItemMessage(hwndDlg, IDC_IMG_PREV, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("previous", FALSE));
+ SendDlgItemMessage(hwndDlg, IDC_IMG_NEXT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("next", FALSE));
+ SendDlgItemMessage(hwndDlg, IDC_IMG_DELETE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("delete", FALSE));
+ SendDlgItemMessage(hwndDlg, IDC_IMG_SAVE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx("save", FALSE));
+
+ // Setting tooltips for buttons
+ SendDlgItemMessage(hwndDlg, IDC_IMG_PREV, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Previous image"), BATF_TCHAR);
+ SendDlgItemMessage(hwndDlg, IDC_IMG_NEXT, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Next image"), BATF_TCHAR);
+ SendDlgItemMessage(hwndDlg, IDC_IMG_DELETE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete image from the list"), BATF_TCHAR);
+ SendDlgItemMessage(hwndDlg, IDC_IMG_SAVE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Save image to disk"), BATF_TCHAR);
+
+ // Set main window image
+ WindowSetIcon(hwndDlg, "image");
+
+ TCHAR *szName = pcli->pfnGetContactDisplayName(dat->hContact, 0), szTitle[128];
+ if (dat->bReceiving)
+ mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("Image from %s"), szName);
+ else
+ mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("Image for %s"), szName);
+ SetWindowText(hwndDlg, szTitle);
- // Store client extents
- GetClientRect(hwndDlg, &rect);
- dat->minSize.cx = rect.right - rect.left;
- dat->minSize.cy = rect.bottom - rect.top;
- }
- return TRUE;
+ // Store client extents
+ GetClientRect(hwndDlg, &rect);
+ dat->minSize.cx = rect.right - rect.left;
+ dat->minSize.cy = rect.bottom - rect.top;
+ }
+ return TRUE;
- case WM_SIZE:
+ case WM_SIZE:
{
UTILRESIZEDIALOG urd = {0};
urd.cbSize = sizeof(urd);
@@ -430,234 +454,233 @@ static INT_PTR CALLBACK gg_img_dlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
return 0;
}
- case WM_SIZING:
+ case WM_SIZING:
+ {
+ RECT *pRect = (RECT *)lParam;
+ if (pRect->right - pRect->left < dat->minSize.cx)
{
- RECT *pRect = (RECT *)lParam;
- if (pRect->right - pRect->left < dat->minSize.cx)
- {
- if (wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT)
- pRect->left = pRect->right - dat->minSize.cx;
- else
- pRect->right = pRect->left + dat->minSize.cx;
- }
- if (pRect->bottom - pRect->top < dat->minSize.cy)
- {
- if (wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOP || wParam == WMSZ_TOPRIGHT)
- pRect->top = pRect->bottom - dat->minSize.cy;
- else
- pRect->bottom = pRect->top + dat->minSize.cy;
- }
+ if (wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT)
+ pRect->left = pRect->right - dat->minSize.cx;
+ else
+ pRect->right = pRect->left + dat->minSize.cx;
}
- return TRUE;
+ if (pRect->bottom - pRect->top < dat->minSize.cy)
+ {
+ if (wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOP || wParam == WMSZ_TOPRIGHT)
+ pRect->top = pRect->bottom - dat->minSize.cy;
+ else
+ pRect->bottom = pRect->top + dat->minSize.cy;
+ }
+ }
+ return TRUE;
- case WM_CLOSE:
- EndDialog(hwndDlg, 0);
- break;
+ case WM_CLOSE:
+ EndDialog(hwndDlg, 0);
+ break;
// Flash the window
- case WM_TIMER:
- if (wParam == TIMERID_FLASHWND)
- FlashWindow(hwndDlg, TRUE);
- break;
+ case WM_TIMER:
+ if (wParam == TIMERID_FLASHWND)
+ FlashWindow(hwndDlg, TRUE);
+ break;
// Kill the timer
- case WM_ACTIVATE:
- if (LOWORD(wParam) != WA_ACTIVE)
- break;
- case WM_MOUSEACTIVATE:
- if (KillTimer(hwndDlg, TIMERID_FLASHWND))
- FlashWindow(hwndDlg, FALSE);
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) != WA_ACTIVE)
break;
+ case WM_MOUSEACTIVATE:
+ if (KillTimer(hwndDlg, TIMERID_FLASHWND))
+ FlashWindow(hwndDlg, FALSE);
+ break;
- case WM_PAINT:
- if (dat->lpImages)
- {
- GGIMAGEENTRY *img = dat->lpImages;
- int i;
+ case WM_PAINT:
+ if (dat->lpImages)
+ {
+ GGIMAGEENTRY *img = dat->lpImages;
+ int i;
- for (i = 1; img && (i < dat->nImg); i++)
- img = img->lpNext;
+ for (i = 1; img && (i < dat->nImg); i++)
+ img = img->lpNext;
- if (!img)
- {
- gg_netlog(dat->gg, "gg_img_dlgproc(): Image was not found on the list. Cannot paint the window.");
- return FALSE;
- }
+ if (!img)
+ {
+ dat->gg->netlog("gg_img_dlgproc(): Image was not found on the list. Cannot paint the window.");
+ return FALSE;
+ }
- if (dat->bReceiving)
- {
- char szTitle[128];
- mir_snprintf(szTitle, sizeof(szTitle),
- "%s (%d / %d)", img->lpszFileName, dat->nImg, dat->nImgTotal);
- SetDlgItemText(hwndDlg, IDC_IMG_NAME, szTitle);
- }
- else
- SetDlgItemText(hwndDlg, IDC_IMG_NAME, img->lpszFileName);
- gg_img_paint(hwndDlg, img);
+ if (dat->bReceiving)
+ {
+ TCHAR szTitle[128];
+ mir_sntprintf(szTitle, SIZEOF(szTitle), _T("%s (%d / %d)"), img->lpszFileName, dat->nImg, dat->nImgTotal);
+ SetDlgItemText(hwndDlg, IDC_IMG_NAME, szTitle);
}
- break;
+ else
+ SetDlgItemText(hwndDlg, IDC_IMG_NAME, img->lpszFileName);
+ gg_img_paint(hwndDlg, img);
+ }
+ break;
- case WM_DESTROY:
- if (dat)
+ case WM_DESTROY:
+ if (dat)
+ {
+ // Deleting all image entries
+ GGIMAGEENTRY *temp, *img = dat->lpImages;
+ GGPROTO *gg = dat->gg;
+ while (temp = img)
{
- // Deleting all image entries
- GGIMAGEENTRY *temp, *img = dat->lpImages;
- GGPROTO *gg = dat->gg;
- while (temp = img)
- {
- img = img->lpNext;
- gg_img_releasepicture(temp);
- }
- ReleaseIconEx("previous", FALSE);
- ReleaseIconEx("next", FALSE);
- ReleaseIconEx("delete", FALSE);
- ReleaseIconEx("save", FALSE);
- WindowFreeIcon(hwndDlg);
- EnterCriticalSection(&gg->img_mutex);
- list_remove(&gg->imagedlgs, dat, 1);
- LeaveCriticalSection(&gg->img_mutex);
+ img = img->lpNext;
+ gg_img_releasepicture(temp);
}
+ ReleaseIconEx("previous", FALSE);
+ ReleaseIconEx("next", FALSE);
+ ReleaseIconEx("delete", FALSE);
+ ReleaseIconEx("save", FALSE);
+ WindowFreeIcon(hwndDlg);
+ EnterCriticalSection(&gg->img_mutex);
+ list_remove(&gg->imagedlgs, dat, 1);
+ LeaveCriticalSection(&gg->img_mutex);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_IMG_CANCEL:
+ EndDialog(hwndDlg, 0);
return TRUE;
- case WM_COMMAND:
- switch (LOWORD(wParam))
+ case IDC_IMG_PREV:
+ if (dat->nImg > 1)
{
- case IDC_IMG_CANCEL:
- EndDialog(hwndDlg, 0);
- return TRUE;
+ dat->nImg--;
+ InvalidateRect(hwndDlg, NULL, FALSE);
+ }
+ return TRUE;
- case IDC_IMG_PREV:
- if (dat->nImg > 1)
- {
- dat->nImg--;
- InvalidateRect(hwndDlg, NULL, FALSE);
- }
- return TRUE;
+ case IDC_IMG_NEXT:
+ if (dat->nImg < dat->nImgTotal)
+ {
+ dat->nImg++;
+ InvalidateRect(hwndDlg, NULL, FALSE);
+ }
+ return TRUE;
- case IDC_IMG_NEXT:
- if (dat->nImg < dat->nImgTotal)
+ case IDC_IMG_DELETE:
+ {
+ GGIMAGEENTRY *del, *img = dat->lpImages;
+ if (dat->nImg == 1)
+ {
+ del = dat->lpImages;
+ dat->lpImages = img->lpNext;
+ }
+ else
+ {
+ int i;
+ for (i = 1; img && (i < dat->nImg - 1); i++)
+ img = img->lpNext;
+ if (!img)
{
- dat->nImg++;
- InvalidateRect(hwndDlg, NULL, FALSE);
+ dat->gg->netlog("gg_img_dlgproc(): Image was not found on the list. Cannot delete it from the list.");
+ return FALSE;
}
- return TRUE;
+ del = img->lpNext;
+ img->lpNext = del->lpNext;
+ dat->nImg --;
+ }
- case IDC_IMG_DELETE:
- {
- GGIMAGEENTRY *del, *img = dat->lpImages;
- if (dat->nImg == 1)
- {
- del = dat->lpImages;
- dat->lpImages = img->lpNext;
- }
- else
- {
- int i;
- for (i = 1; img && (i < dat->nImg - 1); i++)
- img = img->lpNext;
- if (!img)
- {
- gg_netlog(dat->gg, "gg_img_dlgproc(): Image was not found on the list. Cannot delete it from the list.");
- return FALSE;
- }
- del = img->lpNext;
- img->lpNext = del->lpNext;
- dat->nImg --;
- }
-
- if ((-- dat->nImgTotal) == 0)
- EndDialog(hwndDlg, 0);
- else
- InvalidateRect(hwndDlg, NULL, FALSE);
-
- gg_img_releasepicture(del);
- }
- return TRUE;
+ if ((-- dat->nImgTotal) == 0)
+ EndDialog(hwndDlg, 0);
+ else
+ InvalidateRect(hwndDlg, NULL, FALSE);
- case IDC_IMG_SAVE:
- {
- GGIMAGEENTRY *img = dat->lpImages;
- int i;
-
- for (i = 1; img && (i < dat->nImg); i++)
- img = img->lpNext;
- if (!img)
- {
- gg_netlog(dat->gg, "gg_img_dlgproc(): Image was not found on the list. Cannot launch saving.");
- return FALSE;
- }
- gg_img_saveimage(hwndDlg, img);
- }
- return TRUE;
+ gg_img_releasepicture(del);
+ }
+ return TRUE;
- case IDC_IMG_SEND:
- {
- unsigned char format[20];
- char *msg = "\xA0\0";
- GGPROTO *gg = dat->gg;
+ case IDC_IMG_SAVE:
+ {
+ GGIMAGEENTRY *img = dat->lpImages;
+ int i;
- if (dat->lpImages && gg_isonline(gg))
- {
- uin_t uin = (uin_t)DBGetContactSettingDword(dat->hContact, gg->proto.m_szModuleName, GG_KEY_UIN, 0);
- struct gg_msg_richtext_format *r = NULL;
- struct gg_msg_richtext_image *p = NULL;
- LPVOID pvData = NULL;
- int len;
+ for (i = 1; img && (i < dat->nImg); i++)
+ img = img->lpNext;
+ if (!img)
+ {
+ dat->gg->netlog("gg_img_dlgproc(): Image was not found on the list. Cannot launch saving.");
+ return FALSE;
+ }
+ gg_img_saveimage(hwndDlg, img);
+ }
+ return TRUE;
- ((struct gg_msg_richtext*)format)->flag = 2;
+ case IDC_IMG_SEND:
+ {
+ unsigned char format[20];
+ char *msg = "\xA0\0";
+ GGPROTO *gg = dat->gg;
- r = (struct gg_msg_richtext_format *)(format + sizeof(struct gg_msg_richtext));
- r->position = 0;
- r->font = GG_FONT_IMAGE;
+ if (dat->lpImages && gg->isonline())
+ {
+ uin_t uin = (uin_t)db_get_b(dat->hContact, gg->m_szModuleName, GG_KEY_UIN, 0);
+ struct gg_msg_richtext_format *r = NULL;
+ struct gg_msg_richtext_image *p = NULL;
+ LPVOID pvData = NULL;
+ int len;
- p = (struct gg_msg_richtext_image *)(format + sizeof(struct gg_msg_richtext) + sizeof(struct gg_msg_richtext_format));
- p->unknown1 = 0x109;
- p->size = dat->lpImages->nSize;
+ ((struct gg_msg_richtext*)format)->flag = 2;
- dat->lpImages->crc32 = p->crc32 = gg_fix32(gg_crc32(0, dat->lpImages->lpData, dat->lpImages->nSize));
+ r = (struct gg_msg_richtext_format *)(format + sizeof(struct gg_msg_richtext));
+ r->position = 0;
+ r->font = GG_FONT_IMAGE;
- len = sizeof(struct gg_msg_richtext_format) + sizeof(struct gg_msg_richtext_image);
- ((struct gg_msg_richtext*)format)->length = len;
+ p = (struct gg_msg_richtext_image *)(format + sizeof(struct gg_msg_richtext) + sizeof(struct gg_msg_richtext_format));
+ p->unknown1 = 0x109;
+ p->size = dat->lpImages->nSize;
- EnterCriticalSection(&gg->sess_mutex);
- gg_send_message_richtext(gg->sess, GG_CLASS_CHAT, (uin_t)uin, (unsigned char*)msg, format, len + sizeof(struct gg_msg_richtext));
- LeaveCriticalSection(&gg->sess_mutex);
+ dat->lpImages->crc32 = p->crc32 = gg_fix32(gg_crc32(0, (BYTE*)dat->lpImages->lpData, dat->lpImages->nSize));
- // Protect dat from releasing
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)0);
+ len = sizeof(struct gg_msg_richtext_format) + sizeof(struct gg_msg_richtext_image);
+ ((struct gg_msg_richtext*)format)->length = len;
- EndDialog(hwndDlg, 0);
- }
- return TRUE;
- }
- break;
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_send_message_richtext(gg->sess, GG_CLASS_CHAT, (uin_t)uin, (unsigned char*)msg, format, len + sizeof(struct gg_msg_richtext));
+ LeaveCriticalSection(&gg->sess_mutex);
+
+ // Protect dat from releasing
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)0);
+
+ EndDialog(hwndDlg, 0);
+ }
+ return TRUE;
}
break;
+ }
+ break;
- case WM_ADDIMAGE: // lParam == GGIMAGEENTRY *dat
- {
- GGIMAGEENTRY *lpImage = (GGIMAGEENTRY *)lParam;
- GGIMAGEENTRY *lpImages = dat->lpImages;
+ case WM_ADDIMAGE: // lParam == GGIMAGEENTRY *dat
+ {
+ GGIMAGEENTRY *lpImage = (GGIMAGEENTRY *)lParam;
+ GGIMAGEENTRY *lpImages = dat->lpImages;
- if (!dat->lpImages) // first image entry
- dat->lpImages = lpImage;
- else // adding at the end of the list
- {
- while (lpImages->lpNext)
- lpImages = lpImages->lpNext;
- lpImages->lpNext = lpImage;
- }
- dat->nImg = ++ dat->nImgTotal;
+ if (!dat->lpImages) // first image entry
+ dat->lpImages = lpImage;
+ else // adding at the end of the list
+ {
+ while (lpImages->lpNext)
+ lpImages = lpImages->lpNext;
+ lpImages->lpNext = lpImage;
}
- // Fit window to image
- if (!gg_img_fit(hwndDlg))
- InvalidateRect(hwndDlg, NULL, FALSE);
- return TRUE;
+ dat->nImg = ++ dat->nImgTotal;
+ }
+ // Fit window to image
+ if (!gg_img_fit(hwndDlg))
+ InvalidateRect(hwndDlg, NULL, FALSE);
+ return TRUE;
- case WM_CHOOSEIMG:
+ case WM_CHOOSEIMG:
{
- char szFilter[128];
- char szFileName[MAX_PATH];
+ TCHAR szFilter[128];
+ TCHAR szFileName[MAX_PATH];
OPENFILENAME ofn = {0};
gg_img_getfilter(szFilter, sizeof(szFilter));
@@ -668,13 +691,13 @@ static INT_PTR CALLBACK gg_img_dlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
- ofn.lpstrTitle = Translate("Select picture to send");
+ ofn.lpstrTitle = TranslateT("Select picture to send");
ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
if (GetOpenFileName(&ofn))
{
if (dat->lpImages)
gg_img_releasepicture(dat->lpImages);
- if (!(dat->lpImages = (GGIMAGEENTRY *)gg_img_loadpicture(dat->gg, 0, szFileName)))
+ if (!(dat->lpImages = (GGIMAGEENTRY *)dat->gg->img_loadpicture(0, szFileName)))
{
EndDialog(hwndDlg, 0);
return FALSE;
@@ -696,7 +719,8 @@ static INT_PTR CALLBACK gg_img_dlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
////////////////////////////////////////////////////////////////////////////
// Image dialog call thread
-void __cdecl gg_img_dlgcallthread(GGPROTO *gg, void *param)
+
+void __cdecl GGPROTO::img_dlgcallthread(void *param)
{
HWND hMIWnd = 0; //(HWND) CallService(MS_CLUI_GETHWND, 0, 0);
@@ -716,29 +740,28 @@ GGIMAGEDLGDATA *gg_img_recvdlg(GGPROTO *gg, HANDLE hContact)
dat->bReceiving = TRUE;
dat->gg = gg;
ResetEvent(dat->hEvent);
- gg_forkthread(gg, gg_img_dlgcallthread, dat);
+ gg->forkthread(&GGPROTO::img_dlgcallthread, dat);
return dat;
}
////////////////////////////////////////////////////////////////////////////
// Checks if an image is already saved to the specified path
// Returns 1 if yes, 0 if no or -1 if different image on this path is found
-int gg_img_isexists(char *szPath, GGIMAGEENTRY *dat)
+int gg_img_isexists(TCHAR *szPath, GGIMAGEENTRY *dat)
{
struct _stat st;
- if (_stat(szPath, &st) != 0)
+ if (_tstat(szPath, &st) != 0)
return 0;
if (st.st_size == dat->nSize)
{
- char *lpData;
- FILE *fp = fopen(szPath, "rb");
+ FILE *fp = _tfopen(szPath, _T("rb"));
if (!fp) return 0;
- lpData = mir_alloc(dat->nSize);
+ char *lpData = (char*)mir_alloc(dat->nSize);
if (fread(lpData, 1, dat->nSize, fp) == dat->nSize)
{
- if (dat->crc32 == gg_fix32(gg_crc32(0, lpData, dat->nSize)) ||
+ if (dat->crc32 == gg_fix32(gg_crc32(0, (BYTE*)lpData, dat->nSize)) ||
memcmp(lpData, dat->lpData, dat->nSize) == 0)
{
mir_free(lpData);
@@ -755,21 +778,21 @@ int gg_img_isexists(char *szPath, GGIMAGEENTRY *dat)
////////////////////////////////////////////////////////////////////////////
// Determine if image's file name has the proper extension
-char *gg_img_hasextension(const char *filename)
+TCHAR *gg_img_hasextension(TCHAR *filename)
{
if (filename != NULL && *filename != '\0')
{
- char *imgtype = strrchr(filename, '.');
+ TCHAR *imgtype = _tcsrchr(filename, '.');
if (imgtype != NULL)
{
- size_t len = strlen(imgtype);
+ size_t len = _tcslen(imgtype);
imgtype++;
- if (len == 4 && (_stricmp(imgtype, "bmp") == 0 ||
- _stricmp(imgtype, "gif") == 0 ||
- _stricmp(imgtype, "jpg") == 0 ||
- _stricmp(imgtype, "png") == 0))
+ if (len == 4 && (_tcsicmp(imgtype, _T("bmp")) == 0 ||
+ _tcsicmp(imgtype, _T("gif")) == 0 ||
+ _tcsicmp(imgtype, _T("jpg")) == 0 ||
+ _tcsicmp(imgtype, _T("png")) == 0))
return --imgtype;
- if (len == 5 && _stricmp(imgtype, "jpeg") == 0)
+ if (len == 5 && _tcsicmp(imgtype, _T("jpeg")) == 0)
return --imgtype;
}
}
@@ -778,51 +801,47 @@ char *gg_img_hasextension(const char *filename)
////////////////////////////////////////////////////////////////////////////////
// Display received image using message with [img] BBCode
-int gg_img_displayasmsg(GGPROTO *gg, HANDLE hContact, void *img)
+
+int GGPROTO::img_displayasmsg(HANDLE hContact, void *img)
{
GGIMAGEENTRY *dat = (GGIMAGEENTRY *)img;
- char szPath[MAX_PATH], *path = (char*)alloca(MAX_PATH), *pImgext, imgext[6];
+ TCHAR szPath[MAX_PATH], path[MAX_PATH], *pImgext, imgext[6];
size_t tPathLen;
int i, res;
- if (gg->hImagesFolder == NULL || FoldersGetCustomPath(gg->hImagesFolder, path, MAX_PATH, ""))
- {
- char *tmpPath = Utils_ReplaceVars("%miranda_userdata%");
- tPathLen = mir_snprintf(szPath, MAX_PATH, "%s\\%s\\ImageCache", tmpPath, GG_PROTO);
+ if (hImagesFolder == NULL || FoldersGetCustomPathT(hImagesFolder, path, MAX_PATH, _T(""))) {
+ TCHAR *tmpPath = Utils_ReplaceVarsT( _T("%miranda_userdata%"));
+ tPathLen = mir_sntprintf(szPath, MAX_PATH, _T("%s\\%s\\ImageCache"), tmpPath, m_tszUserName);
mir_free(tmpPath);
}
- else
- {
- strcpy(szPath, path);
- tPathLen = strlen(szPath);
+ else {
+ _tcscpy(szPath, path);
+ tPathLen = _tcslen(szPath);
}
- if (_access(szPath, 0))
- CallService(MS_UTILS_CREATEDIRTREE, 0, (LPARAM)szPath);
+ if ( _taccess(szPath, 0))
+ CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)szPath);
- mir_snprintf(szPath + tPathLen, MAX_PATH - tPathLen, "\\%s", dat->lpszFileName);
+ mir_sntprintf(szPath + tPathLen, MAX_PATH - tPathLen, _T("\\%s"), dat->lpszFileName);
if ((pImgext = gg_img_hasextension(szPath)) == NULL)
- pImgext = szPath + strlen(szPath);
- mir_snprintf(imgext, SIZEOF(imgext), "%s", pImgext);
+ pImgext = szPath + _tcslen(szPath);
+ mir_sntprintf(imgext, SIZEOF(imgext), _T("%s"), pImgext);
for (i = 1; ; ++i)
{
if ((res = gg_img_isexists(szPath, dat)) != -1) break;
- mir_snprintf(szPath, MAX_PATH, "%.*s (%u)%s", pImgext - szPath, szPath, i, imgext);
+ mir_sntprintf(szPath, MAX_PATH, _T("%.*s (%u)%s"), pImgext - szPath, szPath, i, imgext);
}
- if (res == 0)
- {
+ if (res == 0) {
// Image file not found, thus create it
- FILE *fp = fopen(szPath, "w+b");
- if (fp)
- {
+ FILE *fp = _tfopen(szPath, _T("w+b"));
+ if (fp) {
res = fwrite(dat->lpData, dat->nSize, 1, fp) > 0;
fclose(fp);
}
}
- if (res != 0)
- {
+ if (res != 0) {
char image_msg[MAX_PATH + 11];
CCSDATA ccs = {0};
PROTORECVEVENT pre = {0};
@@ -834,11 +853,11 @@ int gg_img_displayasmsg(GGPROTO *gg, HANDLE hContact, void *img)
pre.timestamp = time(NULL);
pre.szMessage = image_msg;
CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs);
- gg_netlog(gg, "gg_img_displayasmsg: Image saved to %s.", szPath);
+ netlog("gg_img_displayasmsg: Image saved to %s.", szPath);
}
else
{
- gg_netlog(gg, "gg_img_displayasmsg: Cannot save image to %s.", szPath);
+ netlog("gg_img_displayasmsg: Cannot save image to %s.", szPath);
}
return 0;
@@ -846,9 +865,10 @@ int gg_img_displayasmsg(GGPROTO *gg, HANDLE hContact, void *img)
////////////////////////////////////////////////////////////////////////////
// Return if uin has it's window already opened
-BOOL gg_img_opened(GGPROTO *gg, uin_t uin)
+
+BOOL GGPROTO::img_opened(uin_t uin)
{
- list_t l = gg->imagedlgs;
+ list_t l = imagedlgs;
while (l)
{
GGIMAGEDLGDATA *dat = (GGIMAGEDLGDATA *)l->data;
@@ -861,15 +881,16 @@ BOOL gg_img_opened(GGPROTO *gg, uin_t uin)
////////////////////////////////////////////////////////////////////////////
// Image Module : Looking for window entry, create if not found
-gg_img_display(GGPROTO *gg, HANDLE hContact, void *img)
+
+int GGPROTO::img_display(HANDLE hContact, void *img)
{
- list_t l = gg->imagedlgs;
+ list_t l = imagedlgs;
GGIMAGEDLGDATA *dat;
if (!img) return FALSE;
// Look for already open dialog
- EnterCriticalSection(&gg->img_mutex);
+ EnterCriticalSection(&img_mutex);
while (l)
{
dat = (GGIMAGEDLGDATA *)l->data;
@@ -882,19 +903,19 @@ gg_img_display(GGPROTO *gg, HANDLE hContact, void *img)
if (!dat)
{
- dat = gg_img_recvdlg(gg, hContact);
- dat->uin = DBGetContactSettingDword(hContact, gg->proto.m_szModuleName, GG_KEY_UIN, 0);
+ dat = gg_img_recvdlg(this, hContact);
+ dat->uin = db_get_b(hContact, m_szModuleName, GG_KEY_UIN, 0);
while (WaitForSingleObjectEx(dat->hEvent, INFINITE, TRUE) != WAIT_OBJECT_0);
CloseHandle(dat->hEvent);
dat->hEvent = NULL;
- list_add(&gg->imagedlgs, dat, 0);
+ list_add(&imagedlgs, dat, 0);
}
- LeaveCriticalSection(&gg->img_mutex);
+ LeaveCriticalSection(&img_mutex);
SendMessage(dat->hWnd, WM_ADDIMAGE, 0, (LPARAM)img);
- if (/*DBGetContactSettingByte(NULL, "Chat", "FlashWindowHighlight", 0) != 0 && */
+ if (/*db_get_b(NULL, "Chat", "FlashWindowHighlight", 0) != 0 && */
GetActiveWindow() != dat->hWnd && GetForegroundWindow() != dat->hWnd)
SetTimer(dat->hWnd, TIMERID_FLASHWND, 900, NULL);
@@ -907,43 +928,28 @@ gg_img_display(GGPROTO *gg, HANDLE hContact, void *img)
}
////////////////////////////////////////////////////////////////////////////
-// Image Window : Frees image entry structure
-gg_img_releasepicture(void *img)
-{
- if (!img)
- return FALSE;
- if (((GGIMAGEENTRY *)img)->lpszFileName)
- free(((GGIMAGEENTRY *)img)->lpszFileName);
- if (((GGIMAGEENTRY *)img)->hBitmap)
- DeleteObject(((GGIMAGEENTRY *)img)->hBitmap);
- if (((GGIMAGEENTRY *)img)->lpData)
- free(((GGIMAGEENTRY *)img)->lpData);
- free(img);
-
- return TRUE;
-}
-
-////////////////////////////////////////////////////////////////////////////
// Helper function to determine image file format and the right extension
-const char *gg_img_guessfileextension(const char *lpData)
+
+const TCHAR *gg_img_guessfileextension(const char *lpData)
{
if (lpData != NULL)
{
if (memcmp(lpData, "BM", 2) == 0)
- return ".bmp";
+ return _T(".bmp");
if (memcmp(lpData, "GIF8", 4) == 0)
- return ".gif";
+ return _T(".gif");
if (memcmp(lpData, "\xFF\xD8", 2) == 0)
- return ".jpg";
+ return _T(".jpg");
if (memcmp(lpData, "\x89PNG", 4) == 0)
- return ".png";
+ return _T(".png");
}
- return "";
+ return _T("");
}
////////////////////////////////////////////////////////////////////////////
// Image Window : Loading picture and sending for display
-void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName)
+
+void* GGPROTO::img_loadpicture(gg_event* e, TCHAR *szFileName)
{
GGIMAGEENTRY *dat;
@@ -958,11 +964,10 @@ void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName)
// Copy the file name
if (szFileName)
{
- FILE *fp = fopen(szFileName, "rb");
- if (!fp)
- {
+ FILE *fp = _tfopen(szFileName, _T("rb"));
+ if (!fp) {
free(dat);
- gg_netlog(gg, "gg_img_loadpicture(): fopen(\"%s\", \"rb\") failed.", szFileName);
+ netlog("gg_img_loadpicture(): fopen(\"%s\", \"rb\") failed.", szFileName);
return NULL;
}
fseek(fp, 0, SEEK_END);
@@ -971,7 +976,7 @@ void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName)
{
fclose(fp);
free(dat);
- gg_netlog(gg, "gg_img_loadpicture(): Zero file size \"%s\" failed.", szFileName);
+ netlog("gg_img_loadpicture(): Zero file size \"%s\" failed.", szFileName);
return NULL;
}
// Maximum acceptable image size
@@ -979,47 +984,45 @@ void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName)
{
fclose(fp);
free(dat);
- gg_netlog(gg, "gg_img_loadpicture(): Image size of \"%s\" exceeds 255 KB.", szFileName);
- MessageBox(NULL, Translate("Image exceeds maximum allowed size of 255 KB."), GG_PROTONAME, MB_OK | MB_ICONEXCLAMATION);
+ netlog("gg_img_loadpicture(): Image size of \"%s\" exceeds 255 KB.", szFileName);
+ MessageBox(NULL, TranslateT("Image exceeds maximum allowed size of 255 KB."), m_tszUserName, MB_OK | MB_ICONEXCLAMATION);
return NULL;
}
fseek(fp, 0, SEEK_SET);
- dat->lpData = malloc(dat->nSize);
+ dat->lpData = (char*)malloc(dat->nSize);
if (fread(dat->lpData, 1, dat->nSize, fp) < dat->nSize)
{
free(dat->lpData);
fclose(fp);
free(dat);
- gg_netlog(gg, "gg_img_loadpicture(): Reading file \"%s\" failed.", szFileName);
+ netlog("gg_img_loadpicture(): Reading file \"%s\" failed.", szFileName);
return NULL;
}
fclose(fp);
- dat->lpszFileName = _strdup(szFileName);
+ dat->lpszFileName = _tcsdup(szFileName);
}
// Copy picture from packet
else if (e && e->event.image_reply.filename)
{
dat->nSize = e->event.image_reply.size;
- dat->lpData = malloc(dat->nSize);
+ dat->lpData = (char*)malloc(dat->nSize);
memcpy(dat->lpData, e->event.image_reply.image, dat->nSize);
- if (!gg_img_hasextension(e->event.image_reply.filename))
- {
+ mir_ptr<TCHAR> tmpFileName( mir_a2t(e->event.image_reply.filename));
+ if (!gg_img_hasextension(tmpFileName)) {
// Add missing file extension
- const char *szImgType = gg_img_guessfileextension(dat->lpData);
- if (*szImgType)
- {
- dat->lpszFileName = malloc(strlen(e->event.image_reply.filename) + strlen(szImgType) + 1);
- if (dat->lpszFileName != NULL)
- {
- strcpy(dat->lpszFileName, e->event.image_reply.filename);
- strcat(dat->lpszFileName, szImgType);
+ const TCHAR *szImgType = gg_img_guessfileextension(dat->lpData);
+ if (*szImgType) {
+ dat->lpszFileName = (TCHAR*)calloc(sizeof(TCHAR), lstrlen(tmpFileName) + lstrlen(szImgType) + 1);
+ if (dat->lpszFileName != NULL) {
+ _tcscpy(dat->lpszFileName, tmpFileName);
+ _tcscat(dat->lpszFileName, szImgType);
}
}
}
if (dat->lpszFileName == NULL)
- dat->lpszFileName = _strdup(e->event.image_reply.filename);
+ dat->lpszFileName = _tcsdup( _A2T( e->event.image_reply.filename));
}
////////////////////////////////////////////////////////////////////
@@ -1042,7 +1045,7 @@ void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName)
// If everything is fine return the handle
if (dat->hBitmap) return dat;
- gg_netlog(gg, "gg_img_loadpicture(): MS_IMG_LOAD(MEM) failed.");
+ netlog("gg_img_loadpicture(): MS_IMG_LOAD(MEM) failed.");
if (dat)
{
if (dat->lpData)
@@ -1056,15 +1059,15 @@ void *gg_img_loadpicture(GGPROTO *gg, struct gg_event* e, char *szFileName)
////////////////////////////////////////////////////////////////////////////
// Image Recv : AddEvent proc
-INT_PTR gg_img_recvimage(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
+INT_PTR GGPROTO::img_recvimage(WPARAM wParam, LPARAM lParam)
{
CLISTEVENT *cle = (CLISTEVENT *)lParam;
GGIMAGEENTRY *img = (GGIMAGEENTRY *)cle->lParam;
- gg_netlog(gg, "gg_img_recvimage(%x, %x): Popup new image.", wParam, lParam);
+ netlog("gg_img_recvimage(%x, %x): Popup new image.", wParam, lParam);
if (!img) return FALSE;
- gg_img_display(gg, cle->hContact, img);
+ img_display(cle->hContact, img);
return FALSE;
}
@@ -1104,7 +1107,7 @@ int gg_img_remove(GGIMAGEDLGDATA *dat)
////////////////////////////////////////////////////////////////////////////
//
-GGIMAGEDLGDATA *gg_img_find(GGPROTO *gg, uin_t uin, uint32_t crc32)
+GGIMAGEDLGDATA* gg_img_find(GGPROTO *gg, uin_t uin, uint32_t crc32)
{
int res = 0;
list_t l = gg->imagedlgs;
@@ -1118,7 +1121,7 @@ GGIMAGEDLGDATA *gg_img_find(GGPROTO *gg, uin_t uin, uint32_t crc32)
dat = (GGIMAGEDLGDATA *)l->data;
if (!dat) break;
- c_uin = DBGetContactSettingDword(dat->hContact, dat->gg->proto.m_szModuleName, GG_KEY_UIN, 0);
+ c_uin = db_get_b(dat->hContact, dat->gg->m_szModuleName, GG_KEY_UIN, 0);
if (!dat->bReceiving && dat->lpImages && dat->lpImages->crc32 == crc32 && c_uin == uin)
{
@@ -1130,22 +1133,23 @@ GGIMAGEDLGDATA *gg_img_find(GGPROTO *gg, uin_t uin, uint32_t crc32)
}
LeaveCriticalSection(&gg->img_mutex);
- gg_netlog(gg, "gg_img_find(): Image not found on the list. It might be released before calling this function.");
+ gg->netlog("gg_img_find(): Image not found on the list. It might be released before calling this function.");
return NULL;
}
////////////////////////////////////////////////////////////////////////////
// Image Module : Send on Request
-BOOL gg_img_sendonrequest(GGPROTO *gg, struct gg_event* e)
-{
- GGIMAGEDLGDATA *dat = gg_img_find(gg, e->event.image_request.sender, e->event.image_request.crc32);
- if (!gg || !dat || !gg_isonline(gg)) return FALSE;
+BOOL GGPROTO::img_sendonrequest(gg_event* e)
+{
+ GGIMAGEDLGDATA *dat = gg_img_find(this, e->event.image_request.sender, e->event.image_request.crc32);
+ if (!this || !dat || !isonline())
+ return FALSE;
- EnterCriticalSection(&gg->sess_mutex);
- gg_image_reply(gg->sess, e->event.image_request.sender, dat->lpImages->lpszFileName, dat->lpImages->lpData, dat->lpImages->nSize);
- LeaveCriticalSection(&gg->sess_mutex);
+ EnterCriticalSection(&sess_mutex);
+ gg_image_reply(sess, e->event.image_request.sender, dat->lpImages->lpszFileName, dat->lpImages->lpData, dat->lpImages->nSize);
+ LeaveCriticalSection(&sess_mutex);
gg_img_remove(dat);
@@ -1154,33 +1158,34 @@ BOOL gg_img_sendonrequest(GGPROTO *gg, struct gg_event* e)
////////////////////////////////////////////////////////////////////////////
// Send Image : Run (Thread and main)
-INT_PTR gg_img_sendimg(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
+
+INT_PTR GGPROTO::img_sendimg(WPARAM wParam, LPARAM lParam)
{
HANDLE hContact = (HANDLE)wParam;
GGIMAGEDLGDATA *dat = NULL;
- EnterCriticalSection(&gg->img_mutex);
+ EnterCriticalSection(&img_mutex);
if (!dat)
{
dat = (GGIMAGEDLGDATA *)calloc(1, sizeof(GGIMAGEDLGDATA));
dat->hContact = hContact;
dat->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- dat->gg = gg;
+ dat->gg = this;
ResetEvent(dat->hEvent);
// Create new dialog
- gg_forkthread(gg, gg_img_dlgcallthread, dat);
+ forkthread(&GGPROTO::img_dlgcallthread, dat);
while (WaitForSingleObjectEx(dat->hEvent, INFINITE, TRUE) != WAIT_OBJECT_0);
CloseHandle(dat->hEvent);
dat->hEvent = NULL;
- list_add(&gg->imagedlgs, dat, 0);
+ list_add(&imagedlgs, dat, 0);
}
// Request choose dialog
SendMessage(dat->hWnd, WM_CHOOSEIMG, 0, 0);
- LeaveCriticalSection(&gg->img_mutex);
+ LeaveCriticalSection(&img_mutex);
return 0;
}
diff --git a/protocols/Gadu-Gadu/import.c b/protocols/Gadu-Gadu/import.c
deleted file mode 100644
index 460c417a0e..0000000000
--- a/protocols/Gadu-Gadu/import.c
+++ /dev/null
@@ -1,670 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Gadu-Gadu Plugin for Miranda IM
-//
-// Copyright (c) 2003-2006 Adam Strzelecki <ono+miranda@java.pl>
-//
-// 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 "gg.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// Checks if a group already exists in Miranda with
-// the specified name.
-// Returns 1 if a group with the name exists, returns 0 otherwise.
-int GroupNameExists(const char *name)
-{
- char idstr[33];
- DBVARIANT dbv;
- int i;
-
- for (i = 0; ; i++) {
- _itoa(i, idstr, 10);
- if (DBGetContactSettingString(NULL, "CListGroups", idstr, &dbv)) break;
- if (!strcmp(dbv.pszVal + 1, name)) {
- DBFreeVariant(&dbv);
- return 1;
- }
- DBFreeVariant(&dbv);
- }
- return 0;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Creates a group with a specified name in the
-// Miranda contact list.
-// Returns proper group name
-char *CreateGroup(char *groupName)
-{
- int groupId;
- char groupIdStr[11];
- char groupName2[127];
- char *p;
- DBVARIANT dbv;
-
- // Cleanup group name from weird characters
-
- // Skip first break
- while(*groupName && *groupName == '\\') groupName++;
-
- p = strrchr(groupName, '\\');
- // Cleanup end
- while(p && !(*(p + 1)))
- {
- *p = 0;
- p = strrchr(groupName, '\\');
- }
- // Create upper groups
- if(p)
- {
- *p = 0;
- CreateGroup(groupName);
- *p = '\\';
- }
-
- // Is this a duplicate?
- if (!GroupNameExists(groupName))
- {
- lstrcpyn(groupName2 + 1, groupName, (int)strlen(groupName) + 1);
-
- // Find an unused id
- for (groupId = 0; ; groupId++) {
- _itoa(groupId, groupIdStr,10);
- if (DBGetContactSettingString(NULL, "CListGroups", groupIdStr, &dbv))
- break;
- DBFreeVariant(&dbv);
- }
-
- groupName2[0] = 1|GROUPF_EXPANDED; // 1 is required so we never get '\0'
- DBWriteContactSettingString(NULL, "CListGroups", groupIdStr, groupName2);
- }
- return groupName;
-}
-
-char *gg_makecontacts(GGPROTO *gg, int cr)
-{
- string_t s = string_init(NULL);
- char *contacts;
-
- // Readup contacts
- HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
- while (hContact)
- {
- char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
- if (szProto != NULL && !strcmp(szProto, GG_PROTO) && !DBGetContactSettingByte(hContact, GG_PROTO, "ChatRoom", 0))
- {
- DBVARIANT dbv;
-
- // Readup FirstName
- if (!DBGetContactSettingString(hContact, GG_PROTO, "FirstName", &dbv))
- {
- string_append(s, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- string_append_c(s, ';');
- // Readup LastName
- if (!DBGetContactSettingString(hContact, GG_PROTO, "LastName", &dbv))
- {
- string_append(s, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- string_append_c(s, ';');
-
- // Readup Nick
- if (!DBGetContactSettingString(hContact, "CList", "MyHandle", &dbv) || !DBGetContactSettingString(hContact, GG_PROTO, GG_KEY_NICK, &dbv))
- {
- DBVARIANT dbv2;
- if (!DBGetContactSettingString(hContact, GG_PROTO, "NickName", &dbv2))
- {
- string_append(s, dbv2.pszVal);
- DBFreeVariant(&dbv2);
- }
- else
- string_append(s, dbv.pszVal);
- string_append_c(s, ';');
- string_append(s, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else
- string_append_c(s, ';');
- string_append_c(s, ';');
-
- // Readup Phone (fixed: uses stored editable phones)
- if (!DBGetContactSettingString(hContact, "UserInfo", "MyPhone0", &dbv))
- {
- // Remove SMS postfix
- char *sms = strstr(dbv.pszVal, " SMS");
- if(sms) *sms = 0;
-
- string_append(s, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- string_append_c(s, ';');
- // Readup Group
- if (!DBGetContactSettingString(hContact, "CList", "Group", &dbv))
- {
- string_append(s, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- string_append_c(s, ';');
- // Readup Uin
- string_append(s, ditoa(DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0)));
- string_append_c(s, ';');
- // Readup Mail (fixed: uses stored editable mails)
- if (!DBGetContactSettingString(hContact, "UserInfo", "Mye-mail0", &dbv))
- {
- string_append(s, dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- if(cr)
- string_append(s, ";0;;0;\r\n");
- else
- string_append(s, ";0;;0;\n");
- }
- hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
- }
-
- contacts = string_free(s, 0);
-
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_makecontacts(): \n%s", contacts);
-#endif
-
- return contacts;
-}
-
-char *strndup(char *str, int c)
-{
- char *ret = (char*)malloc(c + 1);
- ret[c] = 0;
- strncpy(ret, str, c);
- return ret;
-}
-
-void gg_parsecontacts(GGPROTO *gg, char *contacts)
-{
- char *p = strchr(contacts, ':'), *n;
- char *strFirstName, *strLastName, *strNickname, *strNick, *strPhone, *strGroup, *strUin, *strMail;
- uin_t uin;
-
- // Skip to proper data
- if(p && p < strchr(contacts, ';')) p++;
- else p = contacts;
-
- while(p)
- {
- // Processing line
- strFirstName = strLastName = strNickname = strNick = strPhone = strGroup = strUin = strMail = NULL;
- uin = 0;
-
- // FirstName
- if(p)
- {
- n = strchr(p, ';');
- if(n && n != p) strFirstName = strndup(p, (n - p));
- p = (n + 1);
- }
- // LastName
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p) strLastName = strndup(p, (n - p));
- p = (n + 1);
- }
- // Nickname
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p) strNickname = strndup(p, (n - p));
- p = (n + 1);
- }
- // Nick
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p) strNick = strndup(p, (n - p));
- p = (n + 1);
- }
- // Phone
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p)
- {
- strPhone = malloc((n - p) + 5);
- strncpy(strPhone, p, (n - p));
- strcpy((strPhone + (n - p)), " SMS"); // Add SMS postfix
- }
- p = (n + 1);
- }
- // Group
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p) strGroup = strndup(p, (n - p));
- p = (n + 1);
- }
- // Uin
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p)
- {
- strUin = strndup(p, (n - p));
- uin = atoi(strUin);
- }
- p = (n + 1);
- }
- // Mail
- if(n && p)
- {
- n = strchr(p, ';');
- if(n && n != p) strMail = strndup(p, (n - p));
- n = strchr(p, '\n');
- p = (n + 1);
- }
- if (!n) p = NULL;
-
- // Loadup contact
- if(uin && strNick)
- {
- HANDLE hContact = gg_getcontact(gg, uin, 1, 1, strNick);
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_parsecontacts(): Found contact %d with nickname \"%s\".", uin, strNick);
-#endif
- // Write group
- if(hContact && strGroup)
- DBWriteContactSettingString(hContact, "CList", "Group", CreateGroup(strGroup));
-
- // Write misc data
- if(hContact && strFirstName) DBWriteContactSettingString(hContact, GG_PROTO, "FirstName", strFirstName);
- if(hContact && strLastName) DBWriteContactSettingString(hContact, GG_PROTO, "LastName", strLastName);
- if(hContact && strPhone) DBWriteContactSettingString(hContact, "UserInfo", "MyPhone0", strPhone); // Store now in User Info
- if(hContact && strMail) DBWriteContactSettingString(hContact, "UserInfo", "Mye-mail0", strMail); // Store now in User Info
- }
-
- // Release stuff
- if(strFirstName) free(strFirstName);
- if(strLastName) free(strLastName);
- if(strNickname) free(strNickname);
- if(strNick) free(strNick);
- if(strPhone) free(strPhone);
- if(strGroup) free(strGroup);
- if(strUin) free(strUin);
- if(strMail) free(strMail);
- }
-}
-
-//////////////////////////////////////////////////////////
-// import from server
-static INT_PTR gg_import_server(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char *password;
- uin_t uin;
- DBVARIANT dbv;
-
- // Check if connected
- if (!gg_isonline(gg))
- {
- MessageBox(NULL,
- Translate("You have to be connected before you can import/export contacts from/to server."),
- GG_PROTONAME, MB_OK | MB_ICONSTOP
- );
- return 0;
- }
-
- // Readup password
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv))
- {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- password = _strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else return 0;
-
- if (!(uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0)))
- return 0;
-
- // Making contacts list
- EnterCriticalSection(&gg->sess_mutex);
- if (gg_userlist_request(gg->sess, GG_USERLIST_GET, NULL) == -1)
- {
- char error[128];
- LeaveCriticalSection(&gg->sess_mutex);
- mir_snprintf(error, sizeof(error), Translate("List cannot be imported because of error:\n\t%s"), strerror(errno));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_import_server(): Cannot import list because of \"%s\".", strerror(errno));
- }
- LeaveCriticalSection(&gg->sess_mutex);
- free(password);
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// remove from server
-static INT_PTR gg_remove_server(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char *password;
- uin_t uin;
- DBVARIANT dbv;
-
- // Check if connected
- if (!gg_isonline(gg))
- {
- MessageBox(NULL,
- Translate("You have to be connected before you can import/export contacts from/to server."),
- GG_PROTONAME, MB_OK | MB_ICONSTOP
- );
- return 0;
- }
-
- // Readup password
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv))
- {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- password = _strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else return 0;
-
- if (!(uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0)))
- return 0;
-
- // Making contacts list
- EnterCriticalSection(&gg->sess_mutex);
- if (gg_userlist_request(gg->sess, GG_USERLIST_PUT, NULL) == -1)
- {
- char error[128];
- LeaveCriticalSection(&gg->sess_mutex);
- mir_snprintf(error, sizeof(error), Translate("List cannot be removeed because of error:\n\t%s"), strerror(errno));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_remove_server(): Cannot remove list because of \"%s\".", strerror(errno));
- }
- LeaveCriticalSection(&gg->sess_mutex);
-
- // Set list removal
- gg->list_remove = TRUE;
- free(password);
-
- return 0;
-}
-
-static INT_PTR gg_import_text(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char str[MAX_PATH] = "\0";
- OPENFILENAME ofn = {0};
- char filter[512], *pfilter;
- struct _stat st;
- FILE *f;
-
- ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
- strncpy(filter, Translate("Text files"), sizeof(filter));
- strncat(filter, " (*.txt)", sizeof(filter) - strlen(filter));
- pfilter = filter + strlen(filter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- strncpy(pfilter, "*.TXT", sizeof(filter) - (pfilter - filter));
- pfilter = pfilter + strlen(pfilter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- strncpy(pfilter, Translate("All Files"), sizeof(filter) - (pfilter - filter));
- strncat(pfilter, " (*)", sizeof(filter) - (pfilter - filter) - strlen(pfilter));
- pfilter = pfilter + strlen(pfilter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- strncpy(pfilter, "*", sizeof(filter) - (pfilter - filter));
- pfilter = pfilter + strlen(pfilter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- *pfilter = '\0';
- ofn.lpstrFilter = filter;
- ofn.lpstrFile = str;
- ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
- ofn.nMaxFile = sizeof(str);
- ofn.nMaxFileTitle = MAX_PATH;
- ofn.lpstrDefExt = "txt";
-
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_import_text()");
-#endif
- if (!GetOpenFileName(&ofn)) return 0;
-
- f = fopen(str, "r");
- _stat(str, &st);
-
- if(f && st.st_size)
- {
- char *contacts = malloc(st.st_size * sizeof(char));
- fread(contacts, sizeof(char), st.st_size, f);
- fclose(f);
- gg_parsecontacts(gg, contacts);
- free(contacts);
-
- MessageBox(
- NULL,
- Translate("List import successful."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
- }
- else
- {
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("List cannot be imported from file \"%s\" because of error:\n\t%s"), str, strerror(errno));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_import_text(): Cannot import list from file \"%s\" because of \"%s\".", str, strerror(errno));
- }
-
- return 0;
-}
-
-static INT_PTR gg_export_text(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char str[MAX_PATH];
- OPENFILENAME ofn = {0};
- char filter[512], *pfilter;
- FILE *f;
-
- strncpy(str, Translate("contacts"), sizeof(str));
- strncat(str, ".txt", sizeof(str) - strlen(str));
-
- ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
- strncpy(filter, Translate("Text files"), sizeof(filter));
- strncat(filter, " (*.txt)", sizeof(filter) - strlen(filter));
- pfilter = filter + strlen(filter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- strncpy(pfilter, "*.TXT", sizeof(filter) - (pfilter - filter));
- pfilter = pfilter + strlen(pfilter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- strncpy(pfilter, Translate("All Files"), sizeof(filter) - (pfilter - filter));
- strncat(pfilter, " (*)", sizeof(filter) - (pfilter - filter) - strlen(pfilter));
- pfilter = pfilter + strlen(pfilter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- strncpy(pfilter, "*", sizeof(filter) - (pfilter - filter));
- pfilter = pfilter + strlen(pfilter) + 1;
- if(pfilter >= filter + sizeof(filter)) return 0;
- *pfilter = '\0';
- ofn.lpstrFilter = filter;
- ofn.lpstrFile = str;
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
- ofn.nMaxFile = sizeof(str);
- ofn.nMaxFileTitle = MAX_PATH;
- ofn.lpstrDefExt = "txt";
-
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_export_text(%s).", str);
-#endif
- if (!GetSaveFileName(&ofn)) return 0;
-
- if(f = fopen(str, "w"))
- {
- char *contacts = gg_makecontacts(gg, 0);
- fwrite(contacts, sizeof(char), strlen(contacts), f);
- fclose(f);
- free(contacts);
-
- MessageBox(
- NULL,
- Translate("List export successful."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
- }
- else
- {
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("List cannot be exported to file \"%s\" because of error:\n\t%s"), str, strerror(errno));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_import_text(): Cannot export list to file \"%s\" because of \"%s\".", str, strerror(errno));
- }
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// export to server
-static INT_PTR gg_export_server(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char *password, *contacts;
- uin_t uin;
- DBVARIANT dbv;
-
- // Check if connected
- if (!gg_isonline(gg))
- {
- MessageBox(NULL,
- Translate("You have to be connected before you can import/export contacts from/to server."),
- GG_PROTONAME, MB_OK | MB_ICONSTOP
- );
- return 0;
- }
-
- // Readup password
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv))
- {
- CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
- password = _strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
- else return 0;
-
- if (!(uin = DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0)))
- return 0;
-
- // Making contacts list
- contacts = gg_makecontacts(gg, 1);
-
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_userlist_request(%s).", contacts);
-#endif
-
- EnterCriticalSection(&gg->sess_mutex);
- if (gg_userlist_request(gg->sess, GG_USERLIST_PUT, contacts) == -1)
- {
- char error[128];
- LeaveCriticalSection(&gg->sess_mutex);
- mir_snprintf(error, sizeof(error), Translate("List cannot be exported because of error:\n\t%s"), strerror(errno));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_export_server(): Cannot export list because of \"%s\".", strerror(errno));
- }
- LeaveCriticalSection(&gg->sess_mutex);
-
- // Set list removal
- gg->list_remove = FALSE;
- free(contacts);
- free(password);
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// Import menus and stuff
-void gg_import_init(GGPROTO *gg, HGENMENU hRoot)
-{
- CLISTMENUITEM mi = {0};
- char service[64];
-
- mi.cbSize = sizeof(mi);
- mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTHANDLE;
- mi.hParentMenu = hRoot;
-
- // Import from server item
- mir_snprintf(service, sizeof(service), GGS_IMPORT_SERVER, GG_PROTO);
- CreateProtoServiceFunction(service, gg_import_server, gg);
- mi.position = 2000500001;
- mi.icolibItem = GetIconHandle(IDI_IMPORT_SERVER);
- mi.pszName = LPGEN("Import List From &Server");
- mi.pszService = service;
- gg->hMainMenu[2] = Menu_AddProtoMenuItem(&mi);
-
- // Import from textfile
- mir_snprintf(service, sizeof(service), GGS_IMPORT_TEXT, GG_PROTO);
- CreateProtoServiceFunction(service, gg_import_text, gg);
- mi.position = 2000500002;
- mi.icolibItem = GetIconHandle(IDI_IMPORT_TEXT);
- mi.pszName = LPGEN("Import List From &Text File...");
- mi.pszService = service;
- gg->hMainMenu[3] = Menu_AddProtoMenuItem(&mi);
-
- // Remove from server
- mir_snprintf(service, sizeof(service), GGS_REMOVE_SERVER, GG_PROTO);
- CreateProtoServiceFunction(service, gg_remove_server, gg);
- mi.position = 2000500003;
- mi.icolibItem = GetIconHandle(IDI_REMOVE_SERVER);
- mi.pszName = LPGEN("&Remove List From Server");
- mi.pszService = service;
- gg->hMainMenu[4] = Menu_AddProtoMenuItem(&mi);
-
- // Export to server
- mir_snprintf(service, sizeof(service), GGS_EXPORT_SERVER, GG_PROTO);
- CreateProtoServiceFunction(service, gg_export_server, gg);
- mi.position = 2005000001;
- mi.icolibItem = GetIconHandle(IDI_EXPORT_SERVER);
- mi.pszName = LPGEN("Export List To &Server");
- mi.pszService = service;
- gg->hMainMenu[5] = Menu_AddProtoMenuItem(&mi);
-
- // Export to textfile
- mir_snprintf(service, sizeof(service), GGS_EXPORT_TEXT, GG_PROTO);
- CreateProtoServiceFunction(service, gg_export_text, gg);
- mi.position = 2005000002;
- mi.icolibItem = GetIconHandle(IDI_EXPORT_TEXT);
- mi.pszName = LPGEN("Export List To &Text File...");
- mi.pszService = service;
- gg->hMainMenu[6] = Menu_AddProtoMenuItem(&mi);
-}
diff --git a/protocols/Gadu-Gadu/import.cpp b/protocols/Gadu-Gadu/import.cpp
new file mode 100644
index 0000000000..c07e2c2006
--- /dev/null
+++ b/protocols/Gadu-Gadu/import.cpp
@@ -0,0 +1,651 @@
+////////////////////////////////////////////////////////////////////////////////
+// Gadu-Gadu Plugin for Miranda IM
+//
+// Copyright (c) 2003-2006 Adam Strzelecki <ono+miranda@java.pl>
+//
+// 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 "gg.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// Checks if a group already exists in Miranda with
+// the specified name.
+// Returns 1 if a group with the name exists, returns 0 otherwise.
+int GroupNameExists(const char *name)
+{
+ char idstr[33];
+ DBVARIANT dbv;
+ int i;
+
+ for (i = 0; ; i++) {
+ _itoa(i, idstr, 10);
+ if (db_get_s(NULL, "CListGroups", idstr, &dbv, DBVT_ASCIIZ)) break;
+ if (!strcmp(dbv.pszVal + 1, name)) {
+ DBFreeVariant(&dbv);
+ return 1;
+ }
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Creates a group with a specified name in the
+// Miranda contact list.
+// Returns proper group name
+
+char *CreateGroup(char *groupName)
+{
+ int groupId;
+ char groupIdStr[11];
+ char groupName2[127];
+ char *p;
+ DBVARIANT dbv;
+
+ // Cleanup group name from weird characters
+
+ // Skip first break
+ while(*groupName && *groupName == '\\') groupName++;
+
+ p = strrchr(groupName, '\\');
+ // Cleanup end
+ while(p && !(*(p + 1)))
+ {
+ *p = 0;
+ p = strrchr(groupName, '\\');
+ }
+ // Create upper groups
+ if (p)
+ {
+ *p = 0;
+ CreateGroup(groupName);
+ *p = '\\';
+ }
+
+ // Is this a duplicate?
+ if (!GroupNameExists(groupName))
+ {
+ lstrcpynA(groupName2 + 1, groupName, (int)strlen(groupName) + 1);
+
+ // Find an unused id
+ for (groupId = 0; ; groupId++) {
+ _itoa(groupId, groupIdStr,10);
+ if (db_get_s(NULL, "CListGroups", groupIdStr, &dbv, DBVT_ASCIIZ))
+ break;
+ DBFreeVariant(&dbv);
+ }
+
+ groupName2[0] = 1|GROUPF_EXPANDED; // 1 is required so we never get '\0'
+ db_set_s(NULL, "CListGroups", groupIdStr, groupName2);
+ }
+ return groupName;
+}
+
+char *gg_makecontacts(GGPROTO *gg, int cr)
+{
+ string_t s = string_init(NULL);
+ char *contacts;
+
+ // Readup contacts
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !strcmp(szProto, gg->m_szModuleName) && !db_get_b(hContact, gg->m_szModuleName, "ChatRoom", 0))
+ {
+ DBVARIANT dbv;
+
+ // Readup FirstName
+ if (!db_get_s(hContact, gg->m_szModuleName, "FirstName", &dbv, DBVT_ASCIIZ))
+ {
+ string_append(s, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ string_append_c(s, ';');
+ // Readup LastName
+ if (!db_get_s(hContact, gg->m_szModuleName, "LastName", &dbv, DBVT_ASCIIZ))
+ {
+ string_append(s, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ string_append_c(s, ';');
+
+ // Readup Nick
+ if (!db_get_s(hContact, "CList", "MyHandle", &dbv, DBVT_ASCIIZ) || !db_get_s(hContact, gg->m_szModuleName, GG_KEY_NICK, &dbv, DBVT_ASCIIZ))
+ {
+ DBVARIANT dbv2;
+ if (!db_get_s(hContact, gg->m_szModuleName, "NickName", &dbv2, DBVT_ASCIIZ))
+ {
+ string_append(s, dbv2.pszVal);
+ DBFreeVariant(&dbv2);
+ }
+ else
+ string_append(s, dbv.pszVal);
+ string_append_c(s, ';');
+ string_append(s, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ string_append_c(s, ';');
+ string_append_c(s, ';');
+
+ // Readup Phone (fixed: uses stored editable phones)
+ if (!db_get_s(hContact, "UserInfo", "MyPhone0", &dbv, DBVT_ASCIIZ))
+ {
+ // Remove SMS postfix
+ char *sms = strstr(dbv.pszVal, " SMS");
+ if (sms) *sms = 0;
+
+ string_append(s, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ string_append_c(s, ';');
+ // Readup Group
+ if (!db_get_s(hContact, "CList", "Group", &dbv, DBVT_ASCIIZ))
+ {
+ string_append(s, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ string_append_c(s, ';');
+ // Readup Uin
+ string_append(s, ditoa(db_get_b(hContact, gg->m_szModuleName, GG_KEY_UIN, 0)));
+ string_append_c(s, ';');
+ // Readup Mail (fixed: uses stored editable mails)
+ if (!db_get_s(hContact, "UserInfo", "Mye-mail0", &dbv, DBVT_ASCIIZ))
+ {
+ string_append(s, dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (cr)
+ string_append(s, ";0;;0;\r\n");
+ else
+ string_append(s, ";0;;0;\n");
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+
+ contacts = string_free(s, 0);
+
+#ifdef DEBUGMODE
+ gg->netlog("gg_makecontacts(): \n%s", contacts);
+#endif
+
+ return contacts;
+}
+
+char *strndup(char *str, int c)
+{
+ char *ret = (char*)malloc(c + 1);
+ ret[c] = 0;
+ strncpy(ret, str, c);
+ return ret;
+}
+
+void GGPROTO::parsecontacts(char *contacts)
+{
+ char *p = strchr(contacts, ':'), *n;
+ char *strFirstName, *strLastName, *strNickname, *strNick, *strPhone, *strGroup, *strUin, *strMail;
+ uin_t uin;
+
+ // Skip to proper data
+ if (p && p < strchr(contacts, ';')) p++;
+ else p = contacts;
+
+ while(p)
+ {
+ // Processing line
+ strFirstName = strLastName = strNickname = strNick = strPhone = strGroup = strUin = strMail = NULL;
+ uin = 0;
+
+ // FirstName
+ if (p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p) strFirstName = strndup(p, (n - p));
+ p = (n + 1);
+ }
+ // LastName
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p) strLastName = strndup(p, (n - p));
+ p = (n + 1);
+ }
+ // Nickname
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p) strNickname = strndup(p, (n - p));
+ p = (n + 1);
+ }
+ // Nick
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p) strNick = strndup(p, (n - p));
+ p = (n + 1);
+ }
+ // Phone
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p)
+ {
+ strPhone = (char*)malloc((n - p) + 5);
+ strncpy(strPhone, p, (n - p));
+ strcpy((strPhone + (n - p)), " SMS"); // Add SMS postfix
+ }
+ p = (n + 1);
+ }
+ // Group
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p) strGroup = strndup(p, (n - p));
+ p = (n + 1);
+ }
+ // Uin
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p)
+ {
+ strUin = strndup(p, (n - p));
+ uin = atoi(strUin);
+ }
+ p = (n + 1);
+ }
+ // Mail
+ if (n && p)
+ {
+ n = strchr(p, ';');
+ if (n && n != p) strMail = strndup(p, (n - p));
+ n = strchr(p, '\n');
+ p = (n + 1);
+ }
+ if (!n) p = NULL;
+
+ // Loadup contact
+ if (uin && strNick)
+ {
+ HANDLE hContact = getcontact(uin, 1, 1, _A2T(strNick));
+#ifdef DEBUGMODE
+ netlog("gg_parsecontacts(): Found contact %d with nickname \"%s\".", uin, strNick);
+#endif
+ // Write group
+ if (hContact && strGroup)
+ db_set_s(hContact, "CList", "Group", CreateGroup(strGroup));
+
+ // Write misc data
+ if (hContact && strFirstName) db_set_s(hContact, m_szModuleName, "FirstName", strFirstName);
+ if (hContact && strLastName) db_set_s(hContact, m_szModuleName, "LastName", strLastName);
+ if (hContact && strPhone) db_set_s(hContact, "UserInfo", "MyPhone0", strPhone); // Store now in User Info
+ if (hContact && strMail) db_set_s(hContact, "UserInfo", "Mye-mail0", strMail); // Store now in User Info
+ }
+
+ // Release stuff
+ if (strFirstName) free(strFirstName);
+ if (strLastName) free(strLastName);
+ if (strNickname) free(strNickname);
+ if (strNick) free(strNick);
+ if (strPhone) free(strPhone);
+ if (strGroup) free(strGroup);
+ if (strUin) free(strUin);
+ if (strMail) free(strMail);
+ }
+}
+
+//////////////////////////////////////////////////////////
+// import from server
+
+INT_PTR GGPROTO::import_server(WPARAM wParam, LPARAM lParam)
+{
+ char *password;
+ uin_t uin;
+ DBVARIANT dbv;
+
+ // Check if connected
+ if (!isonline())
+ {
+ MessageBox(NULL,
+ TranslateT("You have to be connected before you can import/export contacts from/to server."),
+ m_tszUserName, MB_OK | MB_ICONSTOP
+ );
+ return 0;
+ }
+
+ // Readup password
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ))
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ password = _strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else return 0;
+
+ if (!(uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0)))
+ return 0;
+
+ // Making contacts list
+ EnterCriticalSection(&sess_mutex);
+ if (gg_userlist_request(sess, GG_USERLIST_GET, NULL) == -1)
+ {
+ TCHAR error[128];
+ LeaveCriticalSection(&sess_mutex);
+ mir_sntprintf(error, SIZEOF(error), TranslateT("List cannot be imported because of error:\n\t%s"), _tcserror(errno));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
+ netlog("gg_import_server(): Cannot import list because of \"%s\".", strerror(errno));
+ }
+ LeaveCriticalSection(&sess_mutex);
+ free(password);
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////
+// remove from server
+
+INT_PTR GGPROTO::remove_server(WPARAM wParam, LPARAM lParam)
+{
+ char *password;
+ uin_t uin;
+ DBVARIANT dbv;
+
+ // Check if connected
+ if (!isonline())
+ {
+ MessageBox(NULL,
+ TranslateT("You have to be connected before you can import/export contacts from/to server."),
+ m_tszUserName, MB_OK | MB_ICONSTOP
+ );
+ return 0;
+ }
+
+ // Readup password
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ))
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ password = _strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else return 0;
+
+ if (!(uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0)))
+ return 0;
+
+ // Making contacts list
+ EnterCriticalSection(&sess_mutex);
+ if (gg_userlist_request(sess, GG_USERLIST_PUT, NULL) == -1)
+ {
+ TCHAR error[128];
+ LeaveCriticalSection(&sess_mutex);
+ mir_sntprintf(error, SIZEOF(error), TranslateT("List cannot be removeed because of error:\n\t%s"), strerror(errno));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
+ netlog("gg_remove_server(): Cannot remove list because of \"%s\".", strerror(errno));
+ }
+ LeaveCriticalSection(&sess_mutex);
+
+ // Set list removal
+ is_list_remove = TRUE;
+ free(password);
+
+ return 0;
+}
+
+INT_PTR GGPROTO::import_text(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR str[MAX_PATH];
+ TCHAR filter[512], *pfilter;
+ struct _stat st;
+ FILE *f;
+
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ _tcsncpy(filter, TranslateT("Text files"), SIZEOF(filter));
+ _tcsncat(filter, _T(" (*.txt)"), SIZEOF(filter) - _tcslen(filter));
+ pfilter = filter + _tcslen(filter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+
+ _tcsncpy(pfilter, _T("*.TXT"), SIZEOF(filter) - (pfilter - filter));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+ _tcsncpy(pfilter, TranslateT("All Files"), SIZEOF(filter) - (pfilter - filter));
+ _tcsncat(pfilter, _T(" (*)"), SIZEOF(filter) - (pfilter - filter) - _tcslen(pfilter));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+
+ _tcsncpy(pfilter, _T("*"), SIZEOF(filter) - (pfilter - filter));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+
+ *pfilter = '\0';
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.nMaxFile = sizeof(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = _T("txt");
+
+#ifdef DEBUGMODE
+ netlog("gg_import_text()");
+#endif
+ if (!GetOpenFileName(&ofn)) return 0;
+
+ f = _tfopen(str, _T("r"));
+ _tstat(str, &st);
+
+ if (f && st.st_size)
+ {
+ char *contacts = (char*)malloc(st.st_size * sizeof(char));
+ fread(contacts, sizeof(char), st.st_size, f);
+ fclose(f);
+ parsecontacts(contacts);
+ free(contacts);
+
+ MessageBox(NULL, TranslateT("List import successful."), m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ }
+ else
+ {
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("List cannot be imported from file \"%s\" because of error:\n\t%s"), str, _tcserror(errno));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
+ netlog("gg_import_text(): Cannot import list from file \"%S\" because of \"%s\".", str, strerror(errno));
+ }
+
+ return 0;
+}
+
+INT_PTR GGPROTO::export_text(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR str[MAX_PATH];
+ OPENFILENAME ofn = {0};
+ TCHAR filter[512], *pfilter;
+ FILE *f;
+
+ _tcsncpy(str, TranslateT("contacts"), sizeof(str));
+ _tcsncat(str, _T(".txt"), sizeof(str) - _tcslen(str));
+
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ _tcsncpy(filter, TranslateT("Text files"), SIZEOF(filter));
+ _tcsncat(filter, _T(" (*.txt)"), SIZEOF(filter) - _tcslen(filter));
+ pfilter = filter + _tcslen(filter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+ _tcsncpy(pfilter, _T("*.TXT"), SIZEOF(filter) - (pfilter - filter));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+ _tcsncpy(pfilter, TranslateT("All Files"), SIZEOF(filter) - (pfilter - filter));
+ _tcsncat(pfilter, _T(" (*)"), SIZEOF(filter) - (pfilter - filter) - _tcslen(pfilter));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+ _tcsncpy(pfilter, _T("*"), SIZEOF(filter) - (pfilter - filter));
+ pfilter = pfilter + _tcslen(pfilter) + 1;
+ if (pfilter >= filter + SIZEOF(filter))
+ return 0;
+ *pfilter = '\0';
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
+ ofn.nMaxFile = sizeof(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = _T("txt");
+
+#ifdef DEBUGMODE
+ netlog("gg_export_text(%s).", str);
+#endif
+ if (!GetSaveFileName(&ofn)) return 0;
+
+ if (f = _tfopen(str, _T("w"))) {
+ char *contacts = gg_makecontacts(this, 0);
+ fwrite(contacts, sizeof(char), strlen(contacts), f);
+ fclose(f);
+ free(contacts);
+
+ MessageBox(NULL, TranslateT("List export successful."), m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ }
+ else
+ {
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("List cannot be exported to file \"%s\" because of error:\n\t%s"), str, _tcserror(errno));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
+ netlog("gg_import_text(): Cannot export list to file \"%s\" because of \"%s\".", str, strerror(errno));
+ }
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////
+// export to server
+
+INT_PTR GGPROTO::export_server(WPARAM wParam, LPARAM lParam)
+{
+ char *password, *contacts;
+ uin_t uin;
+ DBVARIANT dbv;
+
+ // Check if connected
+ if (!isonline())
+ {
+ MessageBox(NULL,
+ TranslateT("You have to be connected before you can import/export contacts from/to server."),
+ m_tszUserName, MB_OK | MB_ICONSTOP
+ );
+ return 0;
+ }
+
+ // Readup password
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ))
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM) dbv.pszVal);
+ password = _strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else return 0;
+
+ if (!(uin = db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0)))
+ return 0;
+
+ // Making contacts list
+ contacts = gg_makecontacts(this, 1);
+
+#ifdef DEBUGMODE
+ netlog("gg_userlist_request(%s).", contacts);
+#endif
+
+ EnterCriticalSection(&sess_mutex);
+ if (gg_userlist_request(sess, GG_USERLIST_PUT, contacts) == -1)
+ {
+ TCHAR error[128];
+ LeaveCriticalSection(&sess_mutex);
+ mir_sntprintf(error, SIZEOF(error), TranslateT("List cannot be exported because of error:\n\t%s"), _tcserror(errno));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
+ netlog("gg_export_server(): Cannot export list because of \"%s\".", strerror(errno));
+ }
+ LeaveCriticalSection(&sess_mutex);
+
+ // Set list removal
+ is_list_remove = FALSE;
+ free(contacts);
+ free(password);
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////
+// Import menus and stuff
+
+void GGPROTO::import_init(HGENMENU hRoot)
+{
+ CLISTMENUITEM mi = {0};
+ char service[64];
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTHANDLE;
+ mi.hParentMenu = hRoot;
+
+ // Import from server item
+ mir_snprintf(service, sizeof(service), GGS_IMPORT_SERVER, m_szModuleName);
+ createProtoService(service, &GGPROTO::import_server);
+ mi.position = 2000500001;
+ mi.icolibItem = GetIconHandle(IDI_IMPORT_SERVER);
+ mi.pszName = LPGEN("Import List From &Server");
+ mi.pszService = service;
+ hMainMenu[2] = Menu_AddProtoMenuItem(&mi);
+
+ // Import from textfile
+ mir_snprintf(service, sizeof(service), GGS_IMPORT_TEXT, m_szModuleName);
+ createProtoService(service, &GGPROTO::import_text);
+ mi.position = 2000500002;
+ mi.icolibItem = GetIconHandle(IDI_IMPORT_TEXT);
+ mi.pszName = LPGEN("Import List From &Text File...");
+ mi.pszService = service;
+ hMainMenu[3] = Menu_AddProtoMenuItem(&mi);
+
+ // Remove from server
+ mir_snprintf(service, sizeof(service), GGS_REMOVE_SERVER, m_szModuleName);
+ createProtoService(service, &GGPROTO::remove_server);
+ mi.position = 2000500003;
+ mi.icolibItem = GetIconHandle(IDI_REMOVE_SERVER);
+ mi.pszName = LPGEN("&Remove List From Server");
+ mi.pszService = service;
+ hMainMenu[4] = Menu_AddProtoMenuItem(&mi);
+
+ // Export to server
+ mir_snprintf(service, sizeof(service), GGS_EXPORT_SERVER, m_szModuleName);
+ createProtoService(service, &GGPROTO::export_server);
+ mi.position = 2005000001;
+ mi.icolibItem = GetIconHandle(IDI_EXPORT_SERVER);
+ mi.pszName = LPGEN("Export List To &Server");
+ mi.pszService = service;
+ hMainMenu[5] = Menu_AddProtoMenuItem(&mi);
+
+ // Export to textfile
+ mir_snprintf(service, sizeof(service), GGS_EXPORT_TEXT, m_szModuleName);
+ createProtoService(service, &GGPROTO::export_text);
+ mi.position = 2005000002;
+ mi.icolibItem = GetIconHandle(IDI_EXPORT_TEXT);
+ mi.pszName = LPGEN("Export List To &Text File...");
+ mi.pszService = service;
+ hMainMenu[6] = Menu_AddProtoMenuItem(&mi);
+}
diff --git a/protocols/Gadu-Gadu/keepalive.c b/protocols/Gadu-Gadu/keepalive.cpp
index a0c7ddb032..02b661c222 100644
--- a/protocols/Gadu-Gadu/keepalive.c
+++ b/protocols/Gadu-Gadu/keepalive.cpp
@@ -32,16 +32,16 @@ static VOID CALLBACK gg_keepalive(HWND hwnd, UINT message, UINT_PTR idEvent, DWO
//Search for GGPROTO* context
for(i = 0; i < MAX_TIMERS; i++)
- if(g_timers[i]->timer == idEvent)
+ if (g_timers[i]->timer == idEvent)
break;
- if(i < MAX_TIMERS)
+ if (i < MAX_TIMERS)
{
GGPROTO *gg = g_timers[i];
- if (gg_isonline(gg))
+ if (gg->isonline())
{
#ifdef DEBUGMODE
- gg_netlog(gg, "Sending keep-alive");
+ gg->netlog("Sending keep-alive");
#endif
EnterCriticalSection(&gg->sess_mutex);
gg_ping(gg->sess);
@@ -50,43 +50,43 @@ static VOID CALLBACK gg_keepalive(HWND hwnd, UINT message, UINT_PTR idEvent, DWO
}
}
-void gg_keepalive_init(GGPROTO *gg)
+void GGPROTO::keepalive_init()
{
- if (DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_KEEPALIVE, GG_KEYDEF_KEEPALIVE))
+ if (db_get_b(NULL, m_szModuleName, GG_KEY_KEEPALIVE, GG_KEYDEF_KEEPALIVE))
{
int i;
for(i = 0; i < MAX_TIMERS && g_timers[i] != NULL; i++);
- if(i < MAX_TIMERS)
+ if (i < MAX_TIMERS)
{
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_keepalive_init(): Initializing Timer %d", i);
+ netlog("gg_keepalive_init(): Initializing Timer %d", i);
#endif
- gg->timer = SetTimer(NULL, 0, 1000 * 30, gg_keepalive);
- g_timers[i] = gg;
+ timer = SetTimer(NULL, 0, 1000 * 30, gg_keepalive);
+ g_timers[i] = this;
}
}
}
-void gg_keepalive_destroy(GGPROTO *gg)
+void GGPROTO::keepalive_destroy()
{
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_destroykeepalive(): Killing Timer");
+ netlog("gg_destroykeepalive(): Killing Timer");
#endif
- if (gg->timer)
+ if (timer)
{
int i;
- KillTimer(NULL, gg->timer);
+ KillTimer(NULL, timer);
for(i = 0; i < MAX_TIMERS; i++)
- if(g_timers[i] == gg) {
+ if (g_timers[i] == this) {
g_timers[i] = NULL;
break;
}
- gg->timer = 0;
+ timer = 0;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_destroykeepalive(): Killed Timer %d", i);
+ netlog("gg_destroykeepalive(): Killed Timer %d", i);
#endif
}
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_destroykeepalive(): End");
+ netlog("gg_destroykeepalive(): End");
#endif
}
diff --git a/protocols/Gadu-Gadu/libgadu/libgadu.h b/protocols/Gadu-Gadu/libgadu/libgadu.h
index 08d8bb6912..d273d998e1 100644
--- a/protocols/Gadu-Gadu/libgadu/libgadu.h
+++ b/protocols/Gadu-Gadu/libgadu/libgadu.h
@@ -690,7 +690,7 @@ int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient,
int gg_ping(struct gg_session *sess);
int gg_userlist_request(struct gg_session *sess, char type, const char *request);
int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32);
-int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size);
+int gg_image_reply(struct gg_session *sess, uin_t recipient, const TCHAR *filename, const char *image, int size);
int gg_typing_notification(struct gg_session *sess, uin_t recipient, int length);
uint32_t gg_crc32(uint32_t crc, const unsigned char *buf, int len);
@@ -848,7 +848,7 @@ struct gg_event_msg {
uin_t sender; /**< Numer nadawcy/odbiorcy */
int msgclass; /**< Klasa wiadomości */
time_t time; /**< Czas nadania */
- unsigned char *message; /**< Treść wiadomości */
+ char *message; /**< Treść wiadomości */
int recipients_count; /**< Liczba odbiorców konferencji */
uin_t *recipients; /**< Odbiorcy konferencji */
diff --git a/protocols/Gadu-Gadu/libgadu/pthread.c b/protocols/Gadu-Gadu/libgadu/pthread.c
index 2496bb4964..9a8988a358 100644
--- a/protocols/Gadu-Gadu/libgadu/pthread.c
+++ b/protocols/Gadu-Gadu/libgadu/pthread.c
@@ -44,7 +44,7 @@ int pthread_detach(pthread_t *tid)
/* wait for thread termination */
int pthread_join(pthread_t *tid, void **value_ptr)
{
- if(tid->dwThreadId == GetCurrentThreadId())
+ if (tid->dwThreadId == GetCurrentThreadId())
return 35 /*EDEADLK*/;
WaitForSingleObject(tid->hThread, INFINITE);
diff --git a/protocols/Gadu-Gadu/links.c b/protocols/Gadu-Gadu/links.cpp
index 6141358475..53770f0bcd 100644
--- a/protocols/Gadu-Gadu/links.c
+++ b/protocols/Gadu-Gadu/links.cpp
@@ -66,15 +66,15 @@ static INT_PTR gg_parselink(WPARAM wParam, LPARAM lParam)
for (mi.cbSize = sizeof(mi); l; l = l->next)
{
- GGPROTO *gginst = l->data;
+ GGPROTO *gginst = (GGPROTO*)l->data;
mi.flags = CMIM_FLAGS;
- if (gginst->proto.m_iStatus > ID_STATUS_OFFLINE)
+ if (gginst->m_iStatus > ID_STATUS_OFFLINE)
{
++items;
- gg = l->data;
+ gg = (GGPROTO*)l->data;
mi.flags |= CMIM_ICON;
- mi.hIcon = LoadSkinnedProtoIcon(GG_PROTO, gg->proto.m_iStatus);
+ mi.hIcon = LoadSkinnedProtoIcon(gg->m_szModuleName, gg->m_iStatus);
}
else
{
@@ -110,7 +110,7 @@ static INT_PTR gg_parselink(WPARAM wParam, LPARAM lParam)
if (ServiceExists(MS_MSG_SENDMESSAGE))
{
- HANDLE hContact = gg_getcontact(gg, uin, 1, 0, NULL);
+ HANDLE hContact = gg->getcontact(uin, 1, 0, NULL);
if (hContact != NULL)
CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0);
}
@@ -158,16 +158,16 @@ void gg_links_destroy()
DestroyServiceFunction(hServiceParseLink);
}
-void gg_links_instance_init(GGPROTO *gg)
+void GGPROTO::links_instance_init()
{
if (ServiceExists(MS_ASSOCMGR_ADDNEWURLTYPE))
{
TMO_MenuItem tmi = {0};
tmi.cbSize = sizeof(tmi);
tmi.flags = CMIF_TCHAR;
- tmi.ownerdata = gg;
+ tmi.ownerdata = this;
tmi.position = list_count(g_Instances);
- tmi.ptszName = GG_PROTONAME;
- gg->hInstanceMenuItem = (HANDLE)CallService(MO_ADDNEWMENUITEM, (WPARAM)hInstanceMenu, (LPARAM)&tmi);
+ tmi.ptszName = m_tszUserName;
+ hInstanceMenuItem = (HANDLE)CallService(MO_ADDNEWMENUITEM, (WPARAM)hInstanceMenu, (LPARAM)&tmi);
}
}
diff --git a/protocols/Gadu-Gadu/oauth.c b/protocols/Gadu-Gadu/oauth.cpp
index 15f9e592fe..d652a79020 100644
--- a/protocols/Gadu-Gadu/oauth.c
+++ b/protocols/Gadu-Gadu/oauth.cpp
@@ -44,7 +44,7 @@ typedef enum
PLAINTEXT
} OAUTHSIGNMETHOD;
-static int paramsortFunc(OAUTHPARAMETER *p1, OAUTHPARAMETER *p2)
+static int paramsortFunc(const OAUTHPARAMETER *p1, const OAUTHPARAMETER *p2)
{
int res = strcmp(p1->name, p2->name);
return res != 0 ? res : strcmp(p1->value, p2->value);
@@ -119,13 +119,14 @@ char *oauth_uri_escape(const char *str)
}
// generates Signature Base String
-char *oauth_generate_signature(SortedList *params, const char *httpmethod, const char *url)
+
+char *oauth_generate_signature(LIST<OAUTHPARAMETER> &params, const char *httpmethod, const char *url)
{
char *res, *urlenc, *urlnorm;
OAUTHPARAMETER *p;
int i, ix = 0, size;
- if (httpmethod == NULL || url == NULL || !params->realCount) return mir_strdup("");
+ if (httpmethod == NULL || url == NULL || !params.getCount()) return mir_strdup("");
urlnorm = (char *)mir_alloc(strlen(url) + 1);
while (*url) {
@@ -143,8 +144,8 @@ char *oauth_generate_signature(SortedList *params, const char *httpmethod, const
mir_free(urlnorm);
size = (int)strlen(httpmethod) + (int)strlen(urlenc) + 1 + 2;
- for (i = 0; i < params->realCount; i++) {
- p = params->items[i];
+ for (i = 0; i < params.getCount(); i++) {
+ p = params[i];
if (!strcmp(p->name, "oauth_signature")) continue;
if (i > 0) size += 3;
size += (int)strlen(p->name) + (int)strlen(p->value) + 3;
@@ -157,8 +158,8 @@ char *oauth_generate_signature(SortedList *params, const char *httpmethod, const
mir_free(urlenc);
strcat(res, "&");
- for (i = 0; i < params->realCount; i++) {
- p = params->items[i];
+ for (i = 0; i < params.getCount(); i++) {
+ p = params[i];
if (!strcmp(p->name, "oauth_signature")) continue;
if (i > 0) strcat(res, "%26");
strcat(res, p->name);
@@ -169,15 +170,15 @@ char *oauth_generate_signature(SortedList *params, const char *httpmethod, const
return res;
}
-char *oauth_getparam(SortedList *params, const char *name)
+char *oauth_getparam(LIST<OAUTHPARAMETER> &params, const char *name)
{
OAUTHPARAMETER *p;
int i;
if (name == NULL) return NULL;
- for (i = 0; i < params->realCount; i++) {
- p = params->items[i];
+ for (i = 0; i < params.getCount(); i++) {
+ p = params[i];
if (!strcmp(p->name, name))
return p->value;
}
@@ -185,15 +186,15 @@ char *oauth_getparam(SortedList *params, const char *name)
return NULL;
}
-void oauth_setparam(SortedList *params, const char *name, const char *value)
+void oauth_setparam(LIST<OAUTHPARAMETER> &params, const char *name, const char *value)
{
OAUTHPARAMETER *p;
int i;
if (name == NULL) return;
- for (i = 0; i < params->realCount; i++) {
- p = params->items[i];
+ for (i = 0; i < params.getCount(); i++) {
+ p = params[i];
if (!strcmp(p->name, name)) {
mir_free(p->value);
p->value = oauth_uri_escape(value);
@@ -201,30 +202,30 @@ void oauth_setparam(SortedList *params, const char *name, const char *value)
}
}
- p = mir_alloc(sizeof(OAUTHPARAMETER));
+ p = (OAUTHPARAMETER*)mir_alloc(sizeof(OAUTHPARAMETER));
p->name = oauth_uri_escape(name);
p->value = oauth_uri_escape(value);
- List_InsertPtr(params, p);
+ params.insert(p);
}
-void oauth_freeparams(SortedList *params)
+void oauth_freeparams(LIST<OAUTHPARAMETER> &params)
{
OAUTHPARAMETER *p;
int i;
- for (i = 0; i < params->realCount; i++) {
- p = params->items[i];
+ for (i = 0; i < params.getCount(); i++) {
+ p = params[i];
mir_free(p->name);
mir_free(p->value);
}
}
-int oauth_sign_request(SortedList *params, const char *httpmethod, const char *url,
+int oauth_sign_request(LIST<OAUTHPARAMETER> &params, const char *httpmethod, const char *url,
const char *consumer_secret, const char *token_secret)
{
char *sign = NULL, *signmethod;
- if (!params->realCount) return -1;
+ if (!params.getCount()) return -1;
signmethod = oauth_getparam(params, "oauth_signature_method");
if (signmethod == NULL) return -1;
@@ -245,7 +246,7 @@ int oauth_sign_request(SortedList *params, const char *httpmethod, const char *u
mir_free(csenc);
mir_free(tsenc);
- hmacsha1_hash(text, (int)strlen(text), key, (int)strlen(key), digest);
+ hmacsha1_hash((BYTE*)text, (int)strlen(text), (BYTE*)key, (int)strlen(key), digest);
signlen = Netlib_GetBase64EncodedBufferSize(MIR_SHA1_HASH_SIZE);
sign = (char *)mir_alloc(signlen);
@@ -290,7 +291,7 @@ char *oauth_generate_nonce()
str = (char *)mir_alloc(strlen(timestamp) + strlen(randnum) + 1);
strcpy(str, timestamp);
strcat(str, randnum);
- mir_md5_hash(str, (int)strlen(str), digest);
+ mir_md5_hash((BYTE*)str, (int)strlen(str), digest);
mir_free(str);
result = (char *)mir_alloc(32 + 1);
@@ -304,40 +305,36 @@ char *oauth_auth_header(const char *httpmethod, const char *url, OAUTHSIGNMETHOD
const char *consumer_key, const char *consumer_secret,
const char *token, const char *token_secret)
{
- OAUTHPARAMETER *p;
int i, size;
char *res, timestamp[22], *nonce;
- SortedList oauth_parameters = {0};
if (httpmethod == NULL || url == NULL) return NULL;
- oauth_parameters.sortFunc = paramsortFunc;
- oauth_parameters.increment = 1;
-
- oauth_setparam(&oauth_parameters, "oauth_consumer_key", consumer_key);
- oauth_setparam(&oauth_parameters, "oauth_version", "1.0");
+ LIST<OAUTHPARAMETER> oauth_parameters(1, paramsortFunc);
+ oauth_setparam(oauth_parameters, "oauth_consumer_key", consumer_key);
+ oauth_setparam(oauth_parameters, "oauth_version", "1.0");
switch (signmethod) {
- case HMACSHA1: oauth_setparam(&oauth_parameters, "oauth_signature_method", "HMAC-SHA1"); break;
- case RSASHA1: oauth_setparam(&oauth_parameters, "oauth_signature_method", "RSA-SHA1"); break;
- default: oauth_setparam(&oauth_parameters, "oauth_signature_method", "PLAINTEXT"); break;
+ case HMACSHA1: oauth_setparam(oauth_parameters, "oauth_signature_method", "HMAC-SHA1"); break;
+ case RSASHA1: oauth_setparam(oauth_parameters, "oauth_signature_method", "RSA-SHA1"); break;
+ default: oauth_setparam(oauth_parameters, "oauth_signature_method", "PLAINTEXT"); break;
};
mir_snprintf(timestamp, sizeof(timestamp), "%ld", time(NULL));
- oauth_setparam(&oauth_parameters, "oauth_timestamp", timestamp);
+ oauth_setparam(oauth_parameters, "oauth_timestamp", timestamp);
nonce = oauth_generate_nonce();
- oauth_setparam(&oauth_parameters, "oauth_nonce", nonce);
+ oauth_setparam(oauth_parameters, "oauth_nonce", nonce);
mir_free(nonce);
if (token != NULL && *token)
- oauth_setparam(&oauth_parameters, "oauth_token", token);
+ oauth_setparam(oauth_parameters, "oauth_token", token);
- if (oauth_sign_request(&oauth_parameters, httpmethod, url, consumer_secret, token_secret)) {
- oauth_freeparams(&oauth_parameters);
- List_Destroy(&oauth_parameters);
+ if (oauth_sign_request(oauth_parameters, httpmethod, url, consumer_secret, token_secret)) {
+ oauth_freeparams(oauth_parameters);
+ oauth_parameters.destroy();
return NULL;
}
size = 7;
- for (i = 0; i < oauth_parameters.realCount; i++) {
- p = oauth_parameters.items[i];
+ for (i = 0; i < oauth_parameters.getCount(); i++) {
+ OAUTHPARAMETER *p = oauth_parameters[i];
if (i > 0) size++;
size += (int)strlen(p->name) + (int)strlen(p->value) + 3;
}
@@ -345,8 +342,8 @@ char *oauth_auth_header(const char *httpmethod, const char *url, OAUTHSIGNMETHOD
res = (char *)mir_alloc(size);
strcpy(res, "OAuth ");
- for (i = 0; i < oauth_parameters.realCount; i++) {
- p = oauth_parameters.items[i];
+ for (i = 0; i < oauth_parameters.getCount(); i++) {
+ OAUTHPARAMETER *p = oauth_parameters[i];
if (i > 0) strcat(res, ",");
strcat(res, p->name);
strcat(res, "=\"");
@@ -354,28 +351,27 @@ char *oauth_auth_header(const char *httpmethod, const char *url, OAUTHSIGNMETHOD
strcat(res, "\"");
}
- oauth_freeparams(&oauth_parameters);
- List_Destroy(&oauth_parameters);
-
+ oauth_freeparams(oauth_parameters);
+ oauth_parameters.destroy();
return res;
}
-char *gg_oauth_header(GGPROTO *gg, const char *httpmethod, const char *url)
+char* GGPROTO::oauth_header(const char *httpmethod, const char *url)
{
char *res, uin[32], *password = NULL, *token = NULL, *token_secret = NULL;
DBVARIANT dbv;
- UIN2ID(DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0), uin);
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv)) {
+ UIN2ID(db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0), uin);
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ)) {
CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)(int)strlen(dbv.pszVal) + 1, (LPARAM)dbv.pszVal);
password = mir_strdup(dbv.pszVal);
DBFreeVariant(&dbv);
}
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_TOKEN, &dbv)) {
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_TOKEN, &dbv, DBVT_ASCIIZ)) {
token = mir_strdup(dbv.pszVal);
DBFreeVariant(&dbv);
}
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_TOKENSECRET, &dbv)) {
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_TOKENSECRET, &dbv, DBVT_ASCIIZ)) {
CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)(int)strlen(dbv.pszVal) + 1, (LPARAM)dbv.pszVal);
token_secret = mir_strdup(dbv.pszVal);
DBFreeVariant(&dbv);
@@ -389,7 +385,7 @@ char *gg_oauth_header(GGPROTO *gg, const char *httpmethod, const char *url)
return res;
}
-int gg_oauth_receivetoken(GGPROTO *gg)
+int GGPROTO::oauth_receivetoken()
{
NETLIBHTTPHEADER httpHeaders[3];
NETLIBHTTPREQUEST req = {0};
@@ -399,15 +395,15 @@ int gg_oauth_receivetoken(GGPROTO *gg)
int res = 0;
HANDLE nlc = NULL;
- UIN2ID(DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0), uin);
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, &dbv)) {
+ UIN2ID(db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0), uin);
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_PASSWORD, &dbv, DBVT_ASCIIZ)) {
CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal) + 1, (LPARAM)dbv.pszVal);
password = mir_strdup(dbv.pszVal);
DBFreeVariant(&dbv);
}
// 1. Obtaining an Unauthorized Request Token
- gg_netlog(gg, "gg_oauth_receivetoken(): Obtaining an Unauthorized Request Token...");
+ netlog("gg_oauth_receivetoken(): Obtaining an Unauthorized Request Token...");
strcpy(szUrl, "http://api.gadu-gadu.pl/request_token");
str = oauth_auth_header("POST", szUrl, HMACSHA1, uin, password, NULL, NULL);
@@ -424,7 +420,7 @@ int gg_oauth_receivetoken(GGPROTO *gg)
httpHeaders[2].szName = "Accept";
httpHeaders[2].szValue = "*/*";
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) {
nlc = resp->nlc;
if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
@@ -432,32 +428,32 @@ int gg_oauth_receivetoken(GGPROTO *gg)
TCHAR *xmlAction;
TCHAR *tag;
- xmlAction = gg_a2t(resp->pData);
- tag = gg_a2t("result");
+ xmlAction = mir_a2t(resp->pData);
+ tag = mir_a2t("result");
hXml = xi.parseString(xmlAction, 0, tag);
if (hXml != NULL) {
HXML node;
- mir_free(tag); tag = gg_a2t("oauth_token");
+ mir_free(tag); tag = mir_a2t("oauth_token");
node = xi.getChildByPath(hXml, tag, 0);
- token = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
+ token = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
- mir_free(tag); tag = gg_a2t("oauth_token_secret");
+ mir_free(tag); tag = mir_a2t("oauth_token_secret");
node = xi.getChildByPath(hXml, tag, 0);
- token_secret = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
+ token_secret = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
xi.destroyNode(hXml);
}
mir_free(tag);
mir_free(xmlAction);
}
- else gg_netlog(gg, "gg_oauth_receivetoken(): Invalid response code from HTTP request");
+ else netlog("gg_oauth_receivetoken(): Invalid response code from HTTP request");
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
}
- else gg_netlog(gg, "gg_oauth_receivetoken(): No response from HTTP request");
+ else netlog("gg_oauth_receivetoken(): No response from HTTP request");
// 2. Obtaining User Authorization
- gg_netlog(gg, "gg_oauth_receivetoken(): Obtaining User Authorization...");
+ netlog("gg_oauth_receivetoken(): Obtaining User Authorization...");
mir_free(str);
str = oauth_uri_escape("http://www.mojageneracja.pl");
@@ -479,12 +475,12 @@ int gg_oauth_receivetoken(GGPROTO *gg)
req.pData = str;
req.dataLength = (int)strlen(str);
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
- else gg_netlog(gg, "gg_oauth_receivetoken(): No response from HTTP request");
+ else netlog("gg_oauth_receivetoken(): No response from HTTP request");
// 3. Obtaining an Access Token
- gg_netlog(gg, "gg_oauth_receivetoken(): Obtaining an Access Token...");
+ netlog("gg_oauth_receivetoken(): Obtaining an Access Token...");
strcpy(szUrl, "http://api.gadu-gadu.pl/access_token");
mir_free(str);
str = oauth_auth_header("POST", szUrl, HMACSHA1, uin, password, token, token_secret);
@@ -504,52 +500,52 @@ int gg_oauth_receivetoken(GGPROTO *gg)
httpHeaders[1].szName = "Authorization";
httpHeaders[1].szValue = str;
- resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)gg->netlib, (LPARAM)&req);
+ resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)netlib, (LPARAM)&req);
if (resp) {
if (resp->resultCode == 200 && resp->dataLength > 0 && resp->pData) {
HXML hXml;
TCHAR *xmlAction;
TCHAR *tag;
- xmlAction = gg_a2t(resp->pData);
- tag = gg_a2t("result");
+ xmlAction = mir_a2t(resp->pData);
+ tag = mir_a2t("result");
hXml = xi.parseString(xmlAction, 0, tag);
if (hXml != NULL) {
HXML node;
- mir_free(tag); tag = gg_a2t("oauth_token");
+ mir_free(tag); tag = mir_a2t("oauth_token");
node = xi.getChildByPath(hXml, tag, 0);
- token = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
+ token = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
- mir_free(tag); tag = gg_a2t("oauth_token_secret");
+ mir_free(tag); tag = mir_a2t("oauth_token_secret");
node = xi.getChildByPath(hXml, tag, 0);
- token_secret = node != NULL ? gg_t2a(xi.getText(node)) : NULL;
+ token_secret = node != NULL ? mir_t2a(xi.getText(node)) : NULL;
xi.destroyNode(hXml);
}
mir_free(tag);
mir_free(xmlAction);
}
- else gg_netlog(gg, "gg_oauth_receivetoken(): Invalid response code from HTTP request");
+ else netlog("gg_oauth_receivetoken(): Invalid response code from HTTP request");
Netlib_CloseHandle(resp->nlc);
CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp);
}
- else gg_netlog(gg, "gg_oauth_receivetoken(): No response from HTTP request");
+ else netlog("gg_oauth_receivetoken(): No response from HTTP request");
mir_free(password);
mir_free(str);
if (token != NULL && token_secret != NULL) {
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_TOKEN, token);
+ db_set_s(NULL, m_szModuleName, GG_KEY_TOKEN, token);
CallService(MS_DB_CRYPT_ENCODESTRING, (WPARAM)(int)strlen(token_secret) + 1, (LPARAM) token_secret);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_TOKENSECRET, token_secret);
- gg_netlog(gg, "gg_oauth_receivetoken(): Access Token obtained successfully.");
+ db_set_s(NULL, m_szModuleName, GG_KEY_TOKENSECRET, token_secret);
+ netlog("gg_oauth_receivetoken(): Access Token obtained successfully.");
res = 1;
}
else {
- DBDeleteContactSetting(NULL, GG_PROTO, GG_KEY_TOKEN);
- DBDeleteContactSetting(NULL, GG_PROTO, GG_KEY_TOKENSECRET);
- gg_netlog(gg, "gg_oauth_receivetoken(): Failed to obtain Access Token.");
+ db_unset(NULL, m_szModuleName, GG_KEY_TOKEN);
+ db_unset(NULL, m_szModuleName, GG_KEY_TOKENSECRET);
+ netlog("gg_oauth_receivetoken(): Failed to obtain Access Token.");
}
mir_free(token);
mir_free(token_secret);
@@ -557,25 +553,25 @@ int gg_oauth_receivetoken(GGPROTO *gg)
return res;
}
-int gg_oauth_checktoken(GGPROTO *gg, int force)
+int GGPROTO::oauth_checktoken(int force)
{
if (!force) {
char *token = NULL, *token_secret = NULL;
DBVARIANT dbv;
int res = 1;
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_TOKEN, &dbv)) {
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_TOKEN, &dbv, DBVT_ASCIIZ)) {
token = mir_strdup(dbv.pszVal);
DBFreeVariant(&dbv);
}
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_TOKENSECRET, &dbv)) {
+ if (!db_get_s(NULL, m_szModuleName, GG_KEY_TOKENSECRET, &dbv, DBVT_ASCIIZ)) {
CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)(int)strlen(dbv.pszVal) + 1, (LPARAM)dbv.pszVal);
token_secret = mir_strdup(dbv.pszVal);
DBFreeVariant(&dbv);
}
if (token == NULL || token_secret == NULL) {
- res = gg_oauth_receivetoken(gg);
+ res = oauth_receivetoken();
}
mir_free(token);
@@ -584,5 +580,5 @@ int gg_oauth_checktoken(GGPROTO *gg, int force)
return res;
}
- return gg_oauth_receivetoken(gg);
+ return oauth_receivetoken();
}
diff --git a/protocols/Gadu-Gadu/ownerinfo.c b/protocols/Gadu-Gadu/ownerinfo.cpp
index 28cfb4df75..6c37cdb180 100644
--- a/protocols/Gadu-Gadu/ownerinfo.c
+++ b/protocols/Gadu-Gadu/ownerinfo.cpp
@@ -29,7 +29,7 @@ typedef struct
const char *email;
} GG_REMIND_PASS;
-void __cdecl gg_remindpasswordthread(GGPROTO *gg, void *param)
+void __cdecl GGPROTO::remindpasswordthread(void *param)
{
// Connection handle
struct gg_http *h;
@@ -37,52 +37,42 @@ void __cdecl gg_remindpasswordthread(GGPROTO *gg, void *param)
GGTOKEN token;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_remindpasswordthread(): Starting.");
+ netlog("gg_remindpasswordthread(): Starting.");
#endif
if (!rp || !rp->email || !rp->uin || !strlen(rp->email))
{
- if(rp) free(rp);
+ if (rp) free(rp);
return;
}
// Get token
- if (!gg_gettoken(gg, &token)) return;
+ if (!gettoken(&token)) return;
if (!(h = gg_remind_passwd3(rp->uin, rp->email, token.id, token.val, 0)))
{
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Password could not be reminded because of error:\n\t%s"), strerror(errno));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_remindpasswordthread(): Password could not be reminded because of \"%s\".", strerror(errno));
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Password could not be reminded because of error:\n\t%s"), _tcserror(errno));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
+ netlog("gg_remindpasswordthread(): Password could not be reminded because of \"%s\".", strerror(errno));
}
else
{
gg_pubdir_free(h);
- gg_netlog(gg, "gg_remindpasswordthread(): Password remind successful.");
- MessageBox(
- NULL,
- Translate("Password was sent to your e-mail."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
+ netlog("gg_remindpasswordthread(): Password remind successful.");
+ MessageBox(NULL, TranslateT("Password was sent to your e-mail."), m_tszUserName, MB_OK | MB_ICONINFORMATION);
}
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_remindpasswordthread(): End.");
+ netlog("gg_remindpasswordthread(): End.");
#endif
- if(rp) free(rp);
+ if (rp) free(rp);
}
-void gg_remindpassword(GGPROTO *gg, uin_t uin, const char *email)
+void GGPROTO::remindpassword(uin_t uin, const char *email)
{
- GG_REMIND_PASS *rp = malloc(sizeof(GG_REMIND_PASS));
+ GG_REMIND_PASS *rp = (GG_REMIND_PASS*)malloc(sizeof(GG_REMIND_PASS));
rp->uin = uin;
rp->email = email;
- gg_forkthread(gg, gg_remindpasswordthread, rp);
+ forkthread(&GGPROTO::remindpasswordthread, rp);
}
diff --git a/protocols/Gadu-Gadu/popups.c b/protocols/Gadu-Gadu/popups.cpp
index 323bf44590..69ac1c350d 100644
--- a/protocols/Gadu-Gadu/popups.c
+++ b/protocols/Gadu-Gadu/popups.cpp
@@ -20,13 +20,13 @@
#include "gg.h"
-typedef struct _tag_PopupData
+struct PopupData
{
unsigned flags;
- char* title;
- char* text;
+ TCHAR* title;
+ TCHAR* text;
GGPROTO* gg;
-} PopupData;
+};
/////////////////////////////////////////////////////////////////////////////////////////
// Popup plugin window proc
@@ -41,7 +41,7 @@ LRESULT CALLBACK PopupWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
if (puData != NULL)
{
if (puData->flags & GG_POPUP_MULTILOGON)
- gg_sessions_view(puData->gg, 0, 0);
+ puData->gg->sessions_view(0, 0);
}
PUDeletePopUp(hWnd);
break;
@@ -70,13 +70,15 @@ LRESULT CALLBACK PopupWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
/////////////////////////////////////////////////////////////////////////////////////////
// Popup plugin class registration
-void gg_initpopups(GGPROTO* gg)
+void GGPROTO::initpopups()
{
- char szDescr[256], szName[256];
- POPUPCLASS puc = {0};
+ TCHAR szDescr[256];
+ char szName[256];
+ POPUPCLASS puc = {0};
puc.cbSize = sizeof(puc);
puc.PluginWindowProc = PopupWindowProc;
+ puc.flags = PCF_TCHAR;
puc.ptszDescription = szDescr;
puc.pszName = szName;
@@ -85,8 +87,8 @@ void gg_initpopups(GGPROTO* gg)
puc.hIcon = CopyIcon(LoadIconEx("main", FALSE));
ReleaseIconEx("main", FALSE);
puc.iSeconds = 4;
- mir_snprintf(szDescr, SIZEOF(szDescr), "%s/%s", GG_PROTONAME, Translate("Notify"));
- mir_snprintf(szName, SIZEOF(szName), "%s_%s", GG_PROTO, "Notify");
+ mir_sntprintf(szDescr, SIZEOF(szDescr), _T("%s/%s"), m_tszUserName, TranslateT("Notify"));
+ mir_snprintf(szName, SIZEOF(szName), "%s_%s", m_szModuleName, "Notify");
CallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&puc);
puc.ptszDescription = szDescr;
@@ -95,8 +97,8 @@ void gg_initpopups(GGPROTO* gg)
puc.colorText = RGB(255, 245, 225); // Yellow
puc.iSeconds = 60;
puc.hIcon = (HICON)LoadImage(NULL, IDI_WARNING, IMAGE_ICON, 0, 0, LR_SHARED);
- mir_snprintf(szDescr, SIZEOF(szDescr), "%s/%s", GG_PROTONAME, Translate("Error"));
- mir_snprintf(szName, SIZEOF(szName), "%s_%s", GG_PROTO, "Error");
+ mir_sntprintf(szDescr, SIZEOF(szDescr), _T("%s/%s"), m_tszUserName, TranslateT("Error"));
+ mir_snprintf(szName, SIZEOF(szName), "%s_%s", m_szModuleName, "Error");
CallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&puc);
}
@@ -118,9 +120,9 @@ void CALLBACK sttMainThreadCallback(PVOID dwParam)
ppd.pszClassName = szName;
if (puData->flags & GG_POPUP_ERROR || puData->flags & GG_POPUP_WARNING)
- mir_snprintf(szName, SIZEOF(szName), "%s_%s", GG_PROTO, "Error");
+ mir_snprintf(szName, SIZEOF(szName), "%s_%s", gg->m_szModuleName, "Error");
else
- mir_snprintf(szName, SIZEOF(szName), "%s_%s", GG_PROTO, "Notify");
+ mir_snprintf(szName, SIZEOF(szName), "%s_%s", gg->m_szModuleName, "Notify");
CallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&ppd);
}
@@ -132,7 +134,7 @@ void CALLBACK sttMainThreadCallback(PVOID dwParam)
if (puData->flags & GG_POPUP_ONCE)
{
- HWND hWnd = FindWindow(NULL, GG_PROTONAME);
+ HWND hWnd = FindWindow(NULL, gg->m_tszUserName);
while (hWnd != NULL)
{
if (FindWindowEx(hWnd, NULL, NULL, puData->text) != NULL)
@@ -140,14 +142,14 @@ void CALLBACK sttMainThreadCallback(PVOID dwParam)
bShow = FALSE;
break;
}
- hWnd = FindWindowEx(NULL, hWnd, NULL, GG_PROTONAME);
+ hWnd = FindWindowEx(NULL, hWnd, NULL, gg->m_tszUserName);
}
}
if (bShow)
{
UINT uIcon = puData->flags & GG_POPUP_ERROR ? MB_ICONERROR : puData->flags & GG_POPUP_WARNING ? MB_ICONEXCLAMATION : MB_ICONINFORMATION;
- MessageBox(NULL, puData->text, GG_PROTONAME, MB_OK | uIcon);
+ MessageBox(NULL, puData->text, gg->m_tszUserName, MB_OK | uIcon);
}
}
mir_free(puData->title);
@@ -156,7 +158,7 @@ void CALLBACK sttMainThreadCallback(PVOID dwParam)
}
}
-void gg_showpopup(GGPROTO* gg, const char* nickname, const char* msg, int flags)
+void GGPROTO::showpopup(const TCHAR* nickname, const TCHAR* msg, int flags)
{
PopupData* puData;
@@ -164,9 +166,9 @@ void gg_showpopup(GGPROTO* gg, const char* nickname, const char* msg, int flags)
puData = (PopupData*)mir_alloc(sizeof(PopupData));
puData->flags = flags;
- puData->title = mir_strdup(nickname);
- puData->text = mir_strdup(msg);
- puData->gg = gg;
+ puData->title = mir_tstrdup(nickname);
+ puData->text = mir_tstrdup(msg);
+ puData->gg = this;
CallFunctionAsync(sttMainThreadCallback, puData);
}
diff --git a/protocols/Gadu-Gadu/services.c b/protocols/Gadu-Gadu/services.c
deleted file mode 100644
index 420d0666ff..0000000000
--- a/protocols/Gadu-Gadu/services.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Gadu-Gadu Plugin for Miranda IM
-//
-// Copyright (c) 2003-2009 Adam Strzelecki <ono+miranda@java.pl>
-// Copyright (c) 2009-2012 Bartosz Bia³ek
-//
-// 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 "gg.h"
-#include <io.h>
-
-//////////////////////////////////////////////////////////
-// Status mode -> DB
-char *gg_status2db(int status, const char *suffix)
-{
- char *prefix;
- static char str[64];
-
- switch(status) {
- case ID_STATUS_AWAY: prefix = "Away"; break;
- case ID_STATUS_NA: prefix = "Na"; break;
- case ID_STATUS_DND: prefix = "Dnd"; break;
- case ID_STATUS_OCCUPIED: prefix = "Occupied"; break;
- case ID_STATUS_FREECHAT: prefix = "FreeChat"; break;
- case ID_STATUS_ONLINE: prefix = "On"; break;
- case ID_STATUS_OFFLINE: prefix = "Off"; break;
- case ID_STATUS_INVISIBLE: prefix = "Inv"; break;
- case ID_STATUS_ONTHEPHONE: prefix = "Otp"; break;
- case ID_STATUS_OUTTOLUNCH: prefix = "Otl"; break;
- default: return NULL;
- }
- strncpy(str, prefix, sizeof(str));
- strncat(str, suffix, sizeof(str) - strlen(str));
- return str;
-}
-
-//////////////////////////////////////////////////////////
-// checks proto capabilities
-DWORD_PTR gg_getcaps(PROTO_INTERFACE *proto, int type, HANDLE hContact)
-{
- switch (type) {
- case PFLAGNUM_1:
- return PF1_IM | PF1_BASICSEARCH | PF1_EXTSEARCH | PF1_EXTSEARCHUI | PF1_SEARCHBYNAME |
- PF1_MODEMSG | PF1_NUMERICUSERID | PF1_VISLIST | PF1_FILE;
- case PFLAGNUM_2:
- return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_FREECHAT | PF2_INVISIBLE |
- PF2_LONGAWAY;
- case PFLAGNUM_3:
- return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_FREECHAT | PF2_INVISIBLE;
- case PFLAGNUM_4:
- return PF4_NOCUSTOMAUTH | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_IMSENDOFFLINE;
- case PFLAGNUM_5:
- return PF2_LONGAWAY;
- case PFLAG_UNIQUEIDTEXT:
- return (DWORD_PTR) Translate("Gadu-Gadu Number");
- case PFLAG_UNIQUEIDSETTING:
- return (DWORD_PTR) GG_KEY_UIN;
- }
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// loads protocol icon
-HICON gg_geticon(PROTO_INTERFACE *proto, int iconIndex)
-{
- if (LOWORD(iconIndex) == PLI_PROTOCOL)
- {
- HICON hIcon;
- BOOL big;
-
- if (iconIndex & PLIF_ICOLIBHANDLE)
- return (HICON)GetIconHandle(IDI_GG);
-
- big = (iconIndex & PLIF_SMALL) == 0;
- hIcon = LoadIconEx("main", big);
-
- if (iconIndex & PLIF_ICOLIB)
- return hIcon;
-
- hIcon = CopyIcon(hIcon);
- ReleaseIconEx("main", big);
- return hIcon;
- }
-
- return (HICON)NULL;
-}
-
-//////////////////////////////////////////////////////////
-// gets protocol status
-GGINLINE char *gg_getstatusmsg(GGPROTO *gg, int status)
-{
- switch(status)
- {
- case ID_STATUS_ONLINE:
- return gg->modemsg.online;
- break;
- case ID_STATUS_DND:
- return gg->modemsg.dnd;
- break;
- case ID_STATUS_FREECHAT:
- return gg->modemsg.freechat;
- break;
- case ID_STATUS_INVISIBLE:
- return gg->modemsg.invisible;
- break;
- case ID_STATUS_AWAY:
- default:
- return gg->modemsg.away;
- }
-}
-
-//////////////////////////////////////////////////////////
-// sets specified protocol status
-int gg_refreshstatus(GGPROTO *gg, int status)
-{
- if(status == ID_STATUS_OFFLINE)
- {
- gg_disconnect(gg);
- return TRUE;
- }
-
- if (!gg_isonline(gg))
- {
- DWORD exitCode = 0;
- GetExitCodeThread(gg->pth_sess.hThread, &exitCode);
- if (exitCode == STILL_ACTIVE)
- return TRUE;
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_refreshstatus(): Going to connect...");
-#endif
- gg_threadwait(gg, &gg->pth_sess);
- gg->pth_sess.hThread = gg_forkthreadex(gg, gg_mainthread, NULL, &gg->pth_sess.dwThreadId);
- }
- else
- {
- char *szMsg = NULL;
- // Select proper msg
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = mir_strdup(gg_getstatusmsg(gg, status));
- LeaveCriticalSection(&gg->modemsg_mutex);
- if(szMsg)
- {
- gg_netlog(gg, "gg_refreshstatus(): Setting status and away message.");
- EnterCriticalSection(&gg->sess_mutex);
- gg_change_status_descr(gg->sess, status_m2gg(gg, status, szMsg != NULL), szMsg);
- LeaveCriticalSection(&gg->sess_mutex);
- }
- else
- {
- gg_netlog(gg, "gg_refreshstatus(): Setting just status.");
- EnterCriticalSection(&gg->sess_mutex);
- gg_change_status(gg->sess, status_m2gg(gg, status, 0));
- LeaveCriticalSection(&gg->sess_mutex);
- }
- // Change status of the contact with our own UIN (if got yourself added to the contact list)
- gg_changecontactstatus(gg, DBGetContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, 0), status_m2gg(gg, status, szMsg != NULL), szMsg, 0, 0, 0, 0);
- gg_broadcastnewstatus(gg, status);
- mir_free(szMsg);
- }
-
- return TRUE;
-}
-
-//////////////////////////////////////////////////////////
-// normalize gg status
-int gg_normalizestatus(int status)
-{
- switch(status)
- {
- case ID_STATUS_ONLINE:
- return ID_STATUS_ONLINE;
- case ID_STATUS_DND:
- return ID_STATUS_DND;
- case ID_STATUS_FREECHAT:
- return ID_STATUS_FREECHAT;
- case ID_STATUS_OFFLINE:
- return ID_STATUS_OFFLINE;
- case ID_STATUS_INVISIBLE:
- return ID_STATUS_INVISIBLE;
- default:
- return ID_STATUS_AWAY;
- }
-}
-
-//////////////////////////////////////////////////////////
-// sets protocol status
-int gg_setstatus(PROTO_INTERFACE *proto, int iNewStatus)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- int nNewStatus = gg_normalizestatus(iNewStatus);
-
- EnterCriticalSection(&gg->modemsg_mutex);
- gg->proto.m_iDesiredStatus = nNewStatus;
- LeaveCriticalSection(&gg->modemsg_mutex);
-
- // If waiting for connection retry attempt then signal to stop that
- if (gg->hConnStopEvent) SetEvent(gg->hConnStopEvent);
-
- if (gg->proto.m_iStatus == nNewStatus) return 0;
- gg_netlog(gg, "gg_setstatus(): PS_SETSTATUS(%d) normalized to %d.", iNewStatus, nNewStatus);
- gg_refreshstatus(gg, nNewStatus);
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// when messsage received
-int gg_recvmessage(PROTO_INTERFACE *proto, HANDLE hContact, PROTORECVEVENT *pre)
-{
- CCSDATA ccs = { hContact, PSR_MESSAGE, 0, ( LPARAM )pre };
- return CallService(MS_PROTO_RECVMSG, 0, ( LPARAM )&ccs);
-}
-
-//////////////////////////////////////////////////////////
-// when messsage sent
-typedef struct
-{
- HANDLE hContact;
- int seq;
-} GG_SEQ_ACK;
-void __cdecl gg_sendackthread(GGPROTO *gg, void *ack)
-{
- SleepEx(100, FALSE);
- ProtoBroadcastAck(GG_PROTO, ((GG_SEQ_ACK *)ack)->hContact,
- ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) ((GG_SEQ_ACK *)ack)->seq, 0);
- mir_free(ack);
-}
-int gg_sendmessage(PROTO_INTERFACE *proto, HANDLE hContact, int flags, const char *msg)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- uin_t uin;
-
- if (msg && gg_isonline(gg) && (uin = (uin_t)DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0)))
- {
- int seq;
- EnterCriticalSection(&gg->sess_mutex);
- seq = gg_send_message(gg->sess, GG_CLASS_CHAT, uin, msg);
- LeaveCriticalSection(&gg->sess_mutex);
- if (!DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_MSGACK, GG_KEYDEF_MSGACK))
- {
- // Auto-ack message without waiting for server ack
- GG_SEQ_ACK *ack = mir_alloc(sizeof(GG_SEQ_ACK));
- if (ack)
- {
- ack->seq = seq;
- ack->hContact = hContact;
- gg_forkthread(gg, gg_sendackthread, ack);
- }
- }
- return seq;
- }
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// when basic search
-void __cdecl gg_searchthread(GGPROTO *gg, void *empty)
-{
- SleepEx(100, FALSE);
- gg_netlog(gg, "gg_searchthread(): Failed search.");
- ProtoBroadcastAck(GG_PROTO, NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)1, 0);
-}
-HANDLE gg_basicsearch(PROTO_INTERFACE *proto, const PROTOCHAR *id)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- gg_pubdir50_t req;
- char *ida;
-
- if (!gg_isonline(gg))
- return (HANDLE)0;
-
- if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
- {
- gg_forkthread(gg, gg_searchthread, NULL);
- return (HANDLE)1;
- }
-
- ida = gg_t2a(id);
-
- // Add uin and search it
- gg_pubdir50_add(req, GG_PUBDIR50_UIN, ida);
- gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);
-
- mir_free(ida);
-
- EnterCriticalSection(&gg->sess_mutex);
- if (!gg_pubdir50(gg->sess, req))
- {
- LeaveCriticalSection(&gg->sess_mutex);
- gg_forkthread(gg, gg_searchthread, NULL);
- return (HANDLE)1;
- }
- LeaveCriticalSection(&gg->sess_mutex);
- gg_netlog(gg, "gg_basicsearch(): Seq %d.", req->seq);
- gg_pubdir50_free(req);
-
- return (HANDLE)1;
-}
-static HANDLE gg_searchbydetails(PROTO_INTERFACE *proto, const PROTOCHAR *nick, const PROTOCHAR *firstName, const PROTOCHAR *lastName)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- gg_pubdir50_t req;
- unsigned long crc;
- char data[512] = "\0";
-
- // Check if connected and if there's a search data
- if (!gg_isonline(gg))
- return 0;
-
- if (!nick && !firstName && !lastName)
- return 0;
-
- if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
- {
- gg_forkthread(gg, gg_searchthread, NULL);
- return (HANDLE)1;
- }
-
- // Add uin and search it
- if(nick)
- {
- char *nickA = gg_t2a(nick);
- gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, nickA);
- strncat(data, nickA, sizeof(data) - strlen(data));
- mir_free(nickA);
- }
- strncat(data, ".", sizeof(data) - strlen(data));
-
- if(firstName)
- {
- char *firstNameA = gg_t2a(firstName);
- gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, firstNameA);
- strncat(data, firstNameA, sizeof(data) - strlen(data));
- mir_free(firstNameA);
- }
- strncat(data, ".", sizeof(data) - strlen(data));
-
- if(lastName)
- {
- char *lastNameA = gg_t2a(lastName);
- gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, lastNameA);
- strncat(data, lastNameA, sizeof(data) - strlen(data));
- mir_free(lastNameA);
- }
- strncat(data, ".", sizeof(data) - strlen(data));
-
- // Count crc & check if the data was equal if yes do same search with shift
- crc = crc_get(data);
-
- if(crc == gg->last_crc && gg->next_uin)
- gg_pubdir50_add(req, GG_PUBDIR50_START, ditoa(gg->next_uin));
- else
- gg->last_crc = crc;
-
- gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);
-
- EnterCriticalSection(&gg->sess_mutex);
- if (!gg_pubdir50(gg->sess, req))
- {
- LeaveCriticalSection(&gg->sess_mutex);
- gg_forkthread(gg, gg_searchthread, NULL);
- return (HANDLE)1;
- }
- LeaveCriticalSection(&gg->sess_mutex);
- gg_netlog(gg, "gg_searchbyname(): Seq %d.", req->seq);
- gg_pubdir50_free(req);
-
- return (HANDLE)1;
-}
-
-//////////////////////////////////////////////////////////
-// when contact is added to list
-HANDLE gg_addtolist(PROTO_INTERFACE *proto, int flags, PROTOSEARCHRESULT *psr)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- GGSEARCHRESULT *sr = (GGSEARCHRESULT *)psr;
- char *szNick = psr->flags & PSR_UNICODE ? mir_u2a((wchar_t *)sr->hdr.nick) : mir_strdup(sr->hdr.nick);
- uin_t uin;
- HANDLE hContact;
-
- if (psr->cbSize == sizeof(GGSEARCHRESULT))
- uin = sr->uin;
- else
- uin = psr->flags & PSR_UNICODE ? _wtoi((wchar_t*)psr->id) : atoi(psr->id);
-
- hContact = gg_getcontact(gg, uin, 1, flags & PALF_TEMPORARY ? 0 : 1, szNick);
- mir_free(szNick);
-
- return hContact;
-}
-
-//////////////////////////////////////////////////////////
-// user info request
-void __cdecl gg_cmdgetinfothread(GGPROTO *gg, void *hContact)
-{
- SleepEx(100, FALSE);
- gg_netlog(gg, "gg_cmdgetinfothread(): Failed info retreival.");
- ProtoBroadcastAck(GG_PROTO, hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE) 1, 0);
-}
-int gg_getinfo(PROTO_INTERFACE *proto, HANDLE hContact, int infoType)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- gg_pubdir50_t req;
-
- // Custom contact info
- if(hContact)
- {
- if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
- {
- gg_forkthread(gg, gg_cmdgetinfothread, hContact);
- return 1;
- }
-
- // Add uin and search it
- gg_pubdir50_add(req, GG_PUBDIR50_UIN, ditoa((uin_t)DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0)));
- gg_pubdir50_seq_set(req, GG_SEQ_INFO);
-
- gg_netlog(gg, "gg_getinfo(): Requesting user info.", req->seq);
- if(gg_isonline(gg))
- {
- EnterCriticalSection(&gg->sess_mutex);
- if (!gg_pubdir50(gg->sess, req))
- {
- LeaveCriticalSection(&gg->sess_mutex);
- gg_forkthread(gg, gg_cmdgetinfothread, hContact);
- return 1;
- }
- LeaveCriticalSection(&gg->sess_mutex);
- }
- }
- // Own contact info
- else
- {
- if (!(req = gg_pubdir50_new(GG_PUBDIR50_READ)))
- {
- gg_forkthread(gg, gg_cmdgetinfothread, hContact);
- return 1;
- }
-
- // Add seq
- gg_pubdir50_seq_set(req, GG_SEQ_CHINFO);
-
- gg_netlog(gg, "gg_getinfo(): Requesting owner info.", req->seq);
- if(gg_isonline(gg))
- {
- EnterCriticalSection(&gg->sess_mutex);
- if (!gg_pubdir50(gg->sess, req))
- {
- LeaveCriticalSection(&gg->sess_mutex);
- gg_forkthread(gg, gg_cmdgetinfothread, hContact);
- return 1;
- }
- LeaveCriticalSection(&gg->sess_mutex);
- }
- }
- gg_netlog(gg, "gg_getinfo(): Seq %d.", req->seq);
- gg_pubdir50_free(req);
-
- return 1;
-}
-
-//////////////////////////////////////////////////////////
-// when away message is requested
-void __cdecl gg_getawaymsgthread(GGPROTO *gg, void *hContact)
-{
- DBVARIANT dbv;
-
- SleepEx(100, FALSE);
- if (!DBGetContactSettingTString(hContact, "CList", GG_KEY_STATUSDESCR, &dbv))
- {
- ProtoBroadcastAck(GG_PROTO, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE) 1, (LPARAM) dbv.ptszVal);
- gg_netlog(gg, "gg_getawaymsg(): Reading away msg <" TCHAR_STR_PARAM ">.", dbv.ptszVal);
- DBFreeVariant(&dbv);
- }
- else
- ProtoBroadcastAck(GG_PROTO, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE) 1, (LPARAM) NULL);
-}
-HANDLE gg_getawaymsg(PROTO_INTERFACE *proto, HANDLE hContact)
-{
- gg_forkthread((GGPROTO *)proto, gg_getawaymsgthread, hContact);
-
- return (HANDLE)1;
-}
-
-//////////////////////////////////////////////////////////
-// when away message is being set
-int gg_setawaymsg(PROTO_INTERFACE *proto, int iStatus, const PROTOCHAR *msgt)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- int status = gg_normalizestatus(iStatus);
- char **szMsg;
- char *msg = gg_t2a(msgt);
-
- gg_netlog(gg, "gg_setawaymsg(): PS_SETAWAYMSG(%d, \"%s\").", iStatus, msg);
-
- EnterCriticalSection(&gg->modemsg_mutex);
- // Select proper msg
- switch(status)
- {
- case ID_STATUS_ONLINE:
- szMsg = &gg->modemsg.online;
- break;
- case ID_STATUS_AWAY:
- szMsg = &gg->modemsg.away;
- break;
- case ID_STATUS_DND:
- szMsg = &gg->modemsg.dnd;
- break;
- case ID_STATUS_FREECHAT:
- szMsg = &gg->modemsg.freechat;
- break;
- case ID_STATUS_INVISIBLE:
- szMsg = &gg->modemsg.invisible;
- break;
- default:
- LeaveCriticalSection(&gg->modemsg_mutex);
- mir_free(msg);
- return 1;
- }
-
- // Check if we change status here somehow
- if (*szMsg && msg && !strcmp(*szMsg, msg)
- || !*szMsg && (!msg || !*msg))
- {
- if (status == gg->proto.m_iDesiredStatus && gg->proto.m_iDesiredStatus == gg->proto.m_iStatus)
- {
- gg_netlog(gg, "gg_setawaymsg(): Message hasn't been changed, return.");
- LeaveCriticalSection(&gg->modemsg_mutex);
- mir_free(msg);
- return 0;
- }
- }
- else
- {
- if (*szMsg)
- mir_free(*szMsg);
- *szMsg = msg && *msg ? mir_strdup(msg) : NULL;
-#ifdef DEBUGMODE
- gg_netlog(gg, "gg_setawaymsg(): Message changed.");
-#endif
- }
- LeaveCriticalSection(&gg->modemsg_mutex);
-
- // Change the status if it was desired by PS_SETSTATUS
- if (status == gg->proto.m_iDesiredStatus)
- gg_refreshstatus(gg, status);
-
- mir_free(msg);
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// visible lists
-int gg_setapparentmode(PROTO_INTERFACE *proto, HANDLE hContact, int mode)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- DBWriteContactSettingWord(hContact, GG_PROTO, GG_KEY_APPARENT, (WORD)mode);
- gg_notifyuser(gg, hContact, 1);
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// create adv search dialog proc
-INT_PTR CALLBACK gg_advancedsearchdlgproc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
-{
- switch(message)
- {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)_T("")); // 0
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)Translate("Female")); // 1
- SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_ADDSTRING, 0, (LPARAM)Translate("Male")); // 2
- return TRUE;
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDOK:
- SendMessage(GetParent(hwndDlg), WM_COMMAND,MAKEWPARAM(IDOK,BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hwndDlg),IDOK));
- break;
- case IDCANCEL:
-// CheckDlgButton(GetParent(hwndDlg),IDC_ADVANCED,BST_UNCHECKED);
-// SendMessage(GetParent(hwndDlg),WM_COMMAND,MAKEWPARAM(IDC_ADVANCED,BN_CLICKED),(LPARAM)GetDlgItem(GetParent(hwndDlg),IDC_ADVANCED));
- break;
- }
- break;
- }
- return FALSE;
-}
-
-//////////////////////////////////////////////////////////
-// create adv search dialog
-HWND gg_createadvsearchui(PROTO_INTERFACE *proto, HWND owner)
-{
- return CreateDialogParam(hInstance,
- MAKEINTRESOURCE(IDD_GGADVANCEDSEARCH), owner, gg_advancedsearchdlgproc, (LPARAM)(GGPROTO *)proto);
-}
-
-//////////////////////////////////////////////////////////
-// search by advanced
-HWND gg_searchbyadvanced(PROTO_INTERFACE *proto, HWND hwndDlg)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- gg_pubdir50_t req;
- char text[64], data[512] = "\0";
- unsigned long crc;
-
- // Check if connected
- if (!gg_isonline(gg)) return (HWND)0;
-
- if (!(req = gg_pubdir50_new(GG_PUBDIR50_SEARCH)))
- {
- gg_forkthread(gg, gg_searchthread, NULL);
- return (HWND)1;
- }
-
- // Fetch search data
- GetDlgItemText(hwndDlg, IDC_FIRSTNAME, text, sizeof(text));
- if(strlen(text))
- {
- gg_pubdir50_add(req, GG_PUBDIR50_FIRSTNAME, text);
- strncat(data, text, sizeof(data) - strlen(data));
- }
- /* 1 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- GetDlgItemText(hwndDlg, IDC_LASTNAME, text, sizeof(text));
- if(strlen(text))
- {
- gg_pubdir50_add(req, GG_PUBDIR50_LASTNAME, text);
- strncat(data, text, sizeof(data) - strlen(data));
- }
- /* 2 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- GetDlgItemText(hwndDlg, IDC_NICKNAME, text, sizeof(text));
- if(strlen(text))
- {
- gg_pubdir50_add(req, GG_PUBDIR50_NICKNAME, text);
- strncat(data, text, sizeof(data) - strlen(data));
- }
- /* 3 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- GetDlgItemText(hwndDlg, IDC_CITY, text, sizeof(text));
- if(strlen(text))
- {
- gg_pubdir50_add(req, GG_PUBDIR50_CITY, text);
- strncat(data, text, sizeof(data) - strlen(data));
- }
- /* 4 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- GetDlgItemText(hwndDlg, IDC_AGEFROM, text, sizeof(text));
- if(strlen(text))
- {
- int yearTo = atoi(text);
- int yearFrom;
- time_t t = time(NULL);
- struct tm *lt = localtime(&t);
- int ay = lt->tm_year + 1900;
- char age[16];
-
- GetDlgItemText(hwndDlg, IDC_AGETO, age, sizeof(age));
- yearFrom = atoi(age);
-
- // Count & fix ranges
- if (!yearTo)
- yearTo = ay;
- else
- yearTo = ay - yearTo;
- if (!yearFrom)
- yearFrom = 0;
- else
- yearFrom = ay - yearFrom;
- mir_snprintf(text, sizeof(text), "%d %d", yearFrom, yearTo);
-
- gg_pubdir50_add(req, GG_PUBDIR50_BIRTHYEAR, text);
- strncat(data, text, sizeof(data) - strlen(data));
- }
- /* 5 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- switch(SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_GETCURSEL, 0, 0))
- {
- case 1:
- gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_FEMALE);
- strncat(data, GG_PUBDIR50_GENDER_MALE, sizeof(data) - strlen(data));
- break;
- case 2:
- gg_pubdir50_add(req, GG_PUBDIR50_GENDER, GG_PUBDIR50_GENDER_MALE);
- strncat(data, GG_PUBDIR50_GENDER_FEMALE, sizeof(data) - strlen(data));
- break;
- }
- /* 6 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- if(IsDlgButtonChecked(hwndDlg, IDC_ONLYCONNECTED))
- {
- gg_pubdir50_add(req, GG_PUBDIR50_ACTIVE, GG_PUBDIR50_ACTIVE_TRUE);
- strncat(data, GG_PUBDIR50_ACTIVE_TRUE, sizeof(data) - strlen(data));
- }
- /* 7 */ strncat(data, ".", sizeof(data) - strlen(data));
-
- // No data entered
- if(strlen(data) <= 7 || (strlen(data) == 8 && IsDlgButtonChecked(hwndDlg, IDC_ONLYCONNECTED))) return (HWND)0;
-
- // Count crc & check if the data was equal if yes do same search with shift
- crc = crc_get(data);
-
- if(crc == gg->last_crc && gg->next_uin)
- gg_pubdir50_add(req, GG_PUBDIR50_START, ditoa(gg->next_uin));
- else
- gg->last_crc = crc;
-
- gg_pubdir50_seq_set(req, GG_SEQ_SEARCH);
-
- if(gg_isonline(gg))
- {
- EnterCriticalSection(&gg->sess_mutex);
- if (!gg_pubdir50(gg->sess, req))
- {
- LeaveCriticalSection(&gg->sess_mutex);
- gg_forkthread(gg, gg_searchthread, NULL);
- return (HWND)1;
- }
- LeaveCriticalSection(&gg->sess_mutex);
- }
- gg_netlog(gg, "gg_searchbyadvanced(): Seq %d.", req->seq);
- gg_pubdir50_free(req);
-
- return (HWND)1;
-}
-
-//////////////////////////////////////////////////////////
-// gets avatar capabilities
-INT_PTR gg_getavatarcaps(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- switch (wParam) {
- case AF_MAXSIZE:
- ((POINT *)lParam)->x = ((POINT *)lParam)->y = 200;
- return 0;
- case AF_FORMATSUPPORTED:
- return (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF || lParam == PA_FORMAT_PNG);
- case AF_ENABLED:
- return DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS);
- case AF_DONTNEEDDELAYS:
- return 1;
- case AF_MAXFILESIZE:
- return 307200;
- case AF_FETCHALWAYS:
- return 1;
- }
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// gets avatar information
-INT_PTR gg_getavatarinfo(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- PROTO_AVATAR_INFORMATIONT *pai = (PROTO_AVATAR_INFORMATIONT *)lParam;
- char *AvatarHash = NULL, *AvatarSavedHash = NULL;
- TCHAR *AvatarURL = NULL;
- INT_PTR result = GAIR_NOAVATAR;
- DBVARIANT dbv;
- uin_t uin = (uin_t)DBGetContactSettingDword(pai->hContact, GG_PROTO, GG_KEY_UIN, 0);
-
- gg_netlog(gg, "gg_getavatarinfo(): Requesting avatar information for %d.", uin);
-
- pai->filename[0] = 0;
- pai->format = PA_FORMAT_UNKNOWN;
-
- if (!uin || !DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS))
- return GAIR_NOAVATAR;
-
- if (!DBGetContactSettingByte(pai->hContact, GG_PROTO, GG_KEY_AVATARREQUESTED, GG_KEYDEF_AVATARREQUESTED)) {
- gg_requestavatar(gg, pai->hContact, 1);
- return (wParam & GAIF_FORCE) != 0 ? GAIR_WAITFOR : GAIR_NOAVATAR;
- }
- DBDeleteContactSetting(pai->hContact, GG_PROTO, GG_KEY_AVATARREQUESTED);
-
- pai->format = DBGetContactSettingByte(pai->hContact, GG_PROTO, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE);
-
- if (!DBGetContactSettingTString(pai->hContact, GG_PROTO, GG_KEY_AVATARURL, &dbv)) {
- AvatarURL = mir_tstrdup(dbv.ptszVal);
- DBFreeVariant(&dbv);
- }
-
- if (AvatarURL != NULL && _tcslen(AvatarURL) > 0) {
- TCHAR *AvatarName = _tcsrchr(AvatarURL, '/');
- AvatarName++;
- AvatarHash = gg_avatarhash(AvatarName);
- }
-
- if (!DBGetContactSettingString(pai->hContact, GG_PROTO, GG_KEY_AVATARHASH, &dbv)) {
- AvatarSavedHash = mir_strdup(dbv.pszVal);
- DBFreeVariant(&dbv);
- }
-
- if (AvatarHash != NULL && AvatarSavedHash != NULL) {
- gg_getavatarfilename(gg, pai->hContact, pai->filename, sizeof(pai->filename));
- if (!strcmp(AvatarHash, AvatarSavedHash) && !_access(pai->filename, 0)) {
- result = GAIR_SUCCESS;
- }
- else if ((wParam & GAIF_FORCE) != 0) {
- gg_netlog(gg, "gg_getavatarinfo(): Contact %d changed avatar.", uin);
- remove(pai->filename);
- DBWriteContactSettingString(pai->hContact, GG_PROTO, GG_KEY_AVATARHASH, AvatarHash);
- gg_getavatar(gg, pai->hContact, AvatarURL);
- result = GAIR_WAITFOR;
- }
- }
- else if ((wParam & GAIF_FORCE) != 0) {
- if (AvatarHash == NULL && AvatarSavedHash != NULL) {
- gg_netlog(gg, "gg_getavatarinfo(): Contact %d deleted avatar.", uin);
- gg_getavatarfilename(gg, pai->hContact, pai->filename, sizeof(pai->filename));
- remove(pai->filename);
- DBDeleteContactSetting(pai->hContact, GG_PROTO, GG_KEY_AVATARHASH);
- DBDeleteContactSetting(pai->hContact, GG_PROTO, GG_KEY_AVATARURL);
- DBDeleteContactSetting(pai->hContact, GG_PROTO, GG_KEY_AVATARTYPE);
- }
- else if (AvatarHash != NULL && AvatarSavedHash == NULL) {
- gg_netlog(gg, "gg_getavatarinfo(): Contact %d set avatar.", uin);
- DBWriteContactSettingString(pai->hContact, GG_PROTO, GG_KEY_AVATARHASH, AvatarHash);
- gg_getavatar(gg, pai->hContact, AvatarURL);
- result = GAIR_WAITFOR;
- }
- }
-
- mir_free(AvatarHash);
- mir_free(AvatarSavedHash);
- mir_free(AvatarURL);
-
- return result;
-}
-
-//////////////////////////////////////////////////////////
-// gets avatar
-INT_PTR gg_getmyavatar(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- TCHAR *szFilename = (TCHAR*)wParam;
- int len = (int)lParam;
-
- gg_netlog(gg, "gg_getmyavatar(): Requesting user avatar.");
-
- if (szFilename == NULL || len <= 0)
- return -1;
-
- if (!DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS))
- return -2;
-
- gg_getavatarfilename(gg, NULL, szFilename, len);
- return _access(szFilename, 0);
-}
-
-//////////////////////////////////////////////////////////
-// sets avatar
-INT_PTR gg_setmyavatar(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- char *szFilename = (char *)lParam;
-
- if (!DBGetContactSettingByte(NULL, GG_PROTO, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS))
- return -2;
-
- if (szFilename == NULL) {
- MessageBox(
- NULL,
- Translate("To remove your Gadu-Gadu avatar, you must use the MojaGeneracja.pl website."),
- GG_PROTONAME, MB_OK | MB_ICONINFORMATION);
- return -1;
- }
- else {
- char szMyFilename[MAX_PATH];
- gg_getavatarfilename(gg, NULL, szMyFilename, sizeof(szMyFilename));
- if (strcmp(szFilename, szMyFilename) && !CopyFileA(szFilename, szMyFilename, FALSE)) {
- gg_netlog(gg, "gg_setmyavatar(): Failed to set user avatar. File %s could not be created/overwritten.", szMyFilename);
- return -1;
- }
- gg_setavatar(gg, szMyFilename);
- }
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// gets protocol status message
-INT_PTR gg_getmyawaymsg(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- INT_PTR res = 0;
- char *szMsg;
-
- EnterCriticalSection(&gg->modemsg_mutex);
- szMsg = gg_getstatusmsg(gg, wParam ? gg_normalizestatus(wParam) : gg->proto.m_iStatus);
- if(gg_isonline(gg) && szMsg)
- res = (lParam & SGMA_UNICODE) ? (INT_PTR)mir_a2u(szMsg) : (INT_PTR)mir_strdup(szMsg);
- LeaveCriticalSection(&gg->modemsg_mutex);
- return res;
-}
-
-//////////////////////////////////////////////////////////
-// gets account manager GUI
-extern INT_PTR CALLBACK gg_acc_mgr_guidlgproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-static INT_PTR gg_get_acc_mgr_gui(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- return (INT_PTR) CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, gg_acc_mgr_guidlgproc, (LPARAM) gg);
-}
-
-//////////////////////////////////////////////////////////
-// leaves (terminates) conference
-INT_PTR gg_leavechat(GGPROTO *gg, WPARAM wParam, LPARAM lParam)
-{
- HANDLE hContact = (HANDLE)wParam;
- if(hContact)
- CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0);
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// sends a notification that the user is typing a message
-int gg_useristyping(PROTO_INTERFACE *proto, HANDLE hContact, int type)
-{
- GGPROTO *gg = (GGPROTO *)proto;
- uin_t uin = DBGetContactSettingDword(hContact, GG_PROTO, GG_KEY_UIN, 0);
-
- if (!uin || !gg_isonline(gg)) return 0;
-
- if (type == PROTOTYPE_SELFTYPING_ON || type == PROTOTYPE_SELFTYPING_OFF) {
- EnterCriticalSection(&gg->sess_mutex);
- gg_typing_notification(gg->sess, uin, (type == PROTOTYPE_SELFTYPING_ON));
- LeaveCriticalSection(&gg->sess_mutex);
- }
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////
-// Dummies for function that have to be implemented
-
-HANDLE gg_dummy_addtolistbyevent(PROTO_INTERFACE *proto, int flags, int iContact, HANDLE hDbEvent) { return NULL; }
-int gg_dummy_authorize(PROTO_INTERFACE *proto, HANDLE hContact) { return 0; }
-int gg_dummy_authdeny(PROTO_INTERFACE *proto, HANDLE hContact, const TCHAR *szReason) { return 0; }
-int gg_dummy_authrecv(PROTO_INTERFACE *proto, HANDLE hContact, PROTORECVEVENT *pre) { return 0; }
-int gg_dummy_authrequest(PROTO_INTERFACE *proto, HANDLE hContact, const TCHAR *szMessage) { return 0; }
-HANDLE gg_dummy_changeinfo(PROTO_INTERFACE *proto, int iInfoType, void *pInfoData) { return NULL; }
-int gg_dummy_fileresume(PROTO_INTERFACE *proto, HANDLE hTransfer, int *action, const PROTOCHAR** szFilename) { return 0; }
-HANDLE gg_dummy_searchbyemail(PROTO_INTERFACE *proto, const PROTOCHAR *email) { return NULL; }
-int gg_dummy_recvcontacts(PROTO_INTERFACE *proto, HANDLE hContact, PROTORECVEVENT *pre) { return 0; }
-int gg_dummy_recvurl(PROTO_INTERFACE *proto, HANDLE hContact, PROTORECVEVENT *pre) { return 0; }
-int gg_dummy_sendcontacts(PROTO_INTERFACE *proto, HANDLE hContact, int flags, int nContacts, HANDLE *hContactsList) { return 0; }
-int gg_dummy_sendurl(PROTO_INTERFACE *proto, HANDLE hContact, int flags, const char *url) { return 0; }
-int gg_dummy_recvawaymsg(PROTO_INTERFACE *proto, HANDLE hContact, int mode, PROTORECVEVENT *evt) { return 0; }
-int gg_dummy_sendawaymsg(PROTO_INTERFACE *proto, HANDLE hContact, HANDLE hProcess, const char *msg) { return 0; }
-
-//////////////////////////////////////////////////////////
-// Register services
-void gg_registerservices(GGPROTO *gg)
-{
- gg->proto.vtbl->AddToList = gg_addtolist;
- gg->proto.vtbl->AddToListByEvent = gg_dummy_addtolistbyevent;
-
- gg->proto.vtbl->Authorize = gg_dummy_authorize;
- gg->proto.vtbl->AuthDeny = gg_dummy_authdeny;
- gg->proto.vtbl->AuthRecv = gg_dummy_authrecv;
- gg->proto.vtbl->AuthRequest = gg_dummy_authrequest;
-
- gg->proto.vtbl->ChangeInfo = gg_dummy_changeinfo;
-
- gg->proto.vtbl->FileAllow = gg_fileallow;
- gg->proto.vtbl->FileCancel = gg_filecancel;
- gg->proto.vtbl->FileDeny = gg_filedeny;
- gg->proto.vtbl->FileResume = gg_dummy_fileresume;
-
- gg->proto.vtbl->GetCaps = gg_getcaps;
- gg->proto.vtbl->GetIcon = gg_geticon;
- gg->proto.vtbl->GetInfo = gg_getinfo;
-
- gg->proto.vtbl->SearchBasic = gg_basicsearch;
- gg->proto.vtbl->SearchByEmail = gg_dummy_searchbyemail;
- gg->proto.vtbl->SearchByName = gg_searchbydetails;
- gg->proto.vtbl->SearchAdvanced = gg_searchbyadvanced;
- gg->proto.vtbl->CreateExtendedSearchUI = gg_createadvsearchui;
-
- gg->proto.vtbl->RecvContacts = gg_dummy_recvcontacts;
- gg->proto.vtbl->RecvFile = gg_recvfile;
- gg->proto.vtbl->RecvMsg = gg_recvmessage;
- gg->proto.vtbl->RecvUrl = gg_dummy_recvurl;
-
- gg->proto.vtbl->SendContacts = gg_dummy_sendcontacts;
- gg->proto.vtbl->SendFile = gg_sendfile;
- gg->proto.vtbl->SendMsg = gg_sendmessage;
- gg->proto.vtbl->SendUrl = gg_dummy_sendurl;
-
- gg->proto.vtbl->SetApparentMode = gg_setapparentmode;
- gg->proto.vtbl->SetStatus = gg_setstatus;
-
- gg->proto.vtbl->GetAwayMsg = gg_getawaymsg;
- gg->proto.vtbl->RecvAwayMsg = gg_dummy_recvawaymsg;
- gg->proto.vtbl->SendAwayMsg = gg_dummy_sendawaymsg;
- gg->proto.vtbl->SetAwayMsg = gg_setawaymsg;
-
- gg->proto.vtbl->UserIsTyping = gg_useristyping;
-
- gg->proto.vtbl->OnEvent = gg_event;
-
- CreateProtoService(PS_GETAVATARCAPS, gg_getavatarcaps, gg);
- CreateProtoService(PS_GETAVATARINFOT, gg_getavatarinfo, gg);
- CreateProtoService(PS_GETMYAVATAR, gg_getmyavatar, gg);
- CreateProtoService(PS_SETMYAVATAR, gg_setmyavatar, gg);
-
- CreateProtoService(PS_GETMYAWAYMSG, gg_getmyawaymsg, gg);
- CreateProtoService(PS_CREATEACCMGRUI, gg_get_acc_mgr_gui, gg);
-
- CreateProtoService(PS_LEAVECHAT, gg_leavechat, gg);
-}
diff --git a/protocols/Gadu-Gadu/services.cpp b/protocols/Gadu-Gadu/services.cpp
new file mode 100644
index 0000000000..921553fadb
--- /dev/null
+++ b/protocols/Gadu-Gadu/services.cpp
@@ -0,0 +1,330 @@
+////////////////////////////////////////////////////////////////////////////////
+// Gadu-Gadu Plugin for Miranda IM
+//
+// Copyright (c) 2003-2009 Adam Strzelecki <ono+miranda@java.pl>
+// Copyright (c) 2009-2012 Bartosz Bia³ek
+//
+// 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 "gg.h"
+#include <io.h>
+
+//////////////////////////////////////////////////////////
+// Status mode -> DB
+char *gg_status2db(int status, const char *suffix)
+{
+ char *prefix;
+ static char str[64];
+
+ switch(status) {
+ case ID_STATUS_AWAY: prefix = "Away"; break;
+ case ID_STATUS_NA: prefix = "Na"; break;
+ case ID_STATUS_DND: prefix = "Dnd"; break;
+ case ID_STATUS_OCCUPIED: prefix = "Occupied"; break;
+ case ID_STATUS_FREECHAT: prefix = "FreeChat"; break;
+ case ID_STATUS_ONLINE: prefix = "On"; break;
+ case ID_STATUS_OFFLINE: prefix = "Off"; break;
+ case ID_STATUS_INVISIBLE: prefix = "Inv"; break;
+ case ID_STATUS_ONTHEPHONE: prefix = "Otp"; break;
+ case ID_STATUS_OUTTOLUNCH: prefix = "Otl"; break;
+ default: return NULL;
+ }
+ strncpy(str, prefix, sizeof(str));
+ strncat(str, suffix, sizeof(str) - strlen(str));
+ return str;
+}
+
+//////////////////////////////////////////////////////////
+// gets protocol status
+
+char* GGPROTO::getstatusmsg(int status)
+{
+ switch(status) {
+ case ID_STATUS_ONLINE:
+ return modemsg.online;
+ break;
+ case ID_STATUS_DND:
+ return modemsg.dnd;
+ break;
+ case ID_STATUS_FREECHAT:
+ return modemsg.freechat;
+ break;
+ case ID_STATUS_INVISIBLE:
+ return modemsg.invisible;
+ break;
+ case ID_STATUS_AWAY:
+ default:
+ return modemsg.away;
+ }
+}
+
+//////////////////////////////////////////////////////////
+// sets specified protocol status
+
+int GGPROTO::refreshstatus(int status)
+{
+ if (status == ID_STATUS_OFFLINE)
+ {
+ disconnect();
+ return TRUE;
+ }
+
+ if (!isonline())
+ {
+ DWORD exitCode = 0;
+ GetExitCodeThread(pth_sess.hThread, &exitCode);
+ if (exitCode == STILL_ACTIVE)
+ return TRUE;
+#ifdef DEBUGMODE
+ netlog("gg_refreshstatus(): Going to connect...");
+#endif
+ threadwait(&pth_sess);
+ pth_sess.hThread = forkthreadex(&GGPROTO::mainthread, NULL, &pth_sess.dwThreadId);
+ }
+ else
+ {
+ char *szMsg = NULL;
+ // Select proper msg
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = mir_strdup(getstatusmsg(status));
+ LeaveCriticalSection(&modemsg_mutex);
+ if (szMsg)
+ {
+ netlog("gg_refreshstatus(): Setting status and away message.");
+ EnterCriticalSection(&sess_mutex);
+ gg_change_status_descr(sess, status_m2gg(status, szMsg != NULL), szMsg);
+ LeaveCriticalSection(&sess_mutex);
+ }
+ else
+ {
+ netlog("gg_refreshstatus(): Setting just status.");
+ EnterCriticalSection(&sess_mutex);
+ gg_change_status(sess, status_m2gg(status, 0));
+ LeaveCriticalSection(&sess_mutex);
+ }
+ // Change status of the contact with our own UIN (if got yourself added to the contact list)
+ changecontactstatus(db_get_b(NULL, m_szModuleName, GG_KEY_UIN, 0), status_m2gg(status, szMsg != NULL), szMsg, 0, 0, 0, 0);
+ broadcastnewstatus(status);
+ mir_free(szMsg);
+ }
+
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////
+// normalize gg status
+
+int gg_normalizestatus(int status)
+{
+ switch(status) {
+ case ID_STATUS_ONLINE: return ID_STATUS_ONLINE;
+ case ID_STATUS_DND: return ID_STATUS_DND;
+ case ID_STATUS_FREECHAT: return ID_STATUS_FREECHAT;
+ case ID_STATUS_OFFLINE: return ID_STATUS_OFFLINE;
+ case ID_STATUS_INVISIBLE: return ID_STATUS_INVISIBLE;
+ }
+ return ID_STATUS_AWAY;
+}
+
+//////////////////////////////////////////////////////////
+// gets avatar capabilities
+
+INT_PTR GGPROTO::getavatarcaps(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam) {
+ case AF_MAXSIZE:
+ ((POINT *)lParam)->x = ((POINT *)lParam)->y = 200;
+ return 0;
+ case AF_FORMATSUPPORTED:
+ return (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF || lParam == PA_FORMAT_PNG);
+ case AF_ENABLED:
+ return db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS);
+ case AF_DONTNEEDDELAYS:
+ return 1;
+ case AF_MAXFILESIZE:
+ return 307200;
+ case AF_FETCHALWAYS:
+ return 1;
+ }
+ return 0;
+}
+
+//////////////////////////////////////////////////////////
+// gets avatar information
+
+INT_PTR GGPROTO::getavatarinfo(WPARAM wParam, LPARAM lParam)
+{
+ PROTO_AVATAR_INFORMATIONT *pai = (PROTO_AVATAR_INFORMATIONT *)lParam;
+ char *AvatarHash = NULL, *AvatarSavedHash = NULL;
+ char *AvatarURL = NULL;
+ INT_PTR result = GAIR_NOAVATAR;
+ DBVARIANT dbv;
+ uin_t uin = (uin_t)db_get_b(pai->hContact, m_szModuleName, GG_KEY_UIN, 0);
+
+ netlog("gg_getavatarinfo(): Requesting avatar information for %d.", uin);
+
+ pai->filename[0] = 0;
+ pai->format = PA_FORMAT_UNKNOWN;
+
+ if (!uin || !db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS))
+ return GAIR_NOAVATAR;
+
+ if (!db_get_b(pai->hContact, m_szModuleName, GG_KEY_AVATARREQUESTED, GG_KEYDEF_AVATARREQUESTED)) {
+ requestAvatar(pai->hContact, 1);
+ return (wParam & GAIF_FORCE) != 0 ? GAIR_WAITFOR : GAIR_NOAVATAR;
+ }
+ db_unset(pai->hContact, m_szModuleName, GG_KEY_AVATARREQUESTED);
+
+ pai->format = db_get_b(pai->hContact, m_szModuleName, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE);
+
+ if (!db_get_s(pai->hContact, m_szModuleName, GG_KEY_AVATARURL, &dbv, DBVT_ASCIIZ)) {
+ AvatarURL = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ if (AvatarURL != NULL && strlen(AvatarURL) > 0) {
+ char *AvatarName = strrchr(AvatarURL, '/');
+ AvatarName++;
+ AvatarHash = gg_avatarhash(AvatarName);
+ }
+
+ if (!db_get_s(pai->hContact, m_szModuleName, GG_KEY_AVATARHASH, &dbv, DBVT_ASCIIZ)) {
+ AvatarSavedHash = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ if (AvatarHash != NULL && AvatarSavedHash != NULL) {
+ getAvatarFilename(pai->hContact, pai->filename, SIZEOF(pai->filename));
+ if (!strcmp(AvatarHash, AvatarSavedHash) && !_taccess(pai->filename, 0)) {
+ result = GAIR_SUCCESS;
+ }
+ else if ((wParam & GAIF_FORCE) != 0) {
+ netlog("gg_getavatarinfo(): Contact %d changed avatar.", uin);
+ _tremove(pai->filename);
+ db_set_s(pai->hContact, m_szModuleName, GG_KEY_AVATARHASH, AvatarHash);
+ getAvatar(pai->hContact, AvatarURL);
+ result = GAIR_WAITFOR;
+ }
+ }
+ else if ((wParam & GAIF_FORCE) != 0) {
+ if (AvatarHash == NULL && AvatarSavedHash != NULL) {
+ netlog("gg_getavatarinfo(): Contact %d deleted avatar.", uin);
+ getAvatarFilename(pai->hContact, pai->filename, sizeof(pai->filename));
+ _tremove(pai->filename);
+ db_unset(pai->hContact, m_szModuleName, GG_KEY_AVATARHASH);
+ db_unset(pai->hContact, m_szModuleName, GG_KEY_AVATARURL);
+ db_unset(pai->hContact, m_szModuleName, GG_KEY_AVATARTYPE);
+ }
+ else if (AvatarHash != NULL && AvatarSavedHash == NULL) {
+ netlog("gg_getavatarinfo(): Contact %d set avatar.", uin);
+ db_set_s(pai->hContact, m_szModuleName, GG_KEY_AVATARHASH, AvatarHash);
+ getAvatar(pai->hContact, AvatarURL);
+ result = GAIR_WAITFOR;
+ }
+ }
+
+ mir_free(AvatarHash);
+ mir_free(AvatarSavedHash);
+ mir_free(AvatarURL);
+
+ return result;
+}
+
+//////////////////////////////////////////////////////////
+// gets avatar
+
+INT_PTR GGPROTO::getmyavatar(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR *szFilename = (TCHAR*)wParam;
+ int len = (int)lParam;
+
+ netlog("gg_getmyavatar(): Requesting user avatar.");
+
+ if (szFilename == NULL || len <= 0)
+ return -1;
+
+ if (!db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS))
+ return -2;
+
+ getAvatarFilename(NULL, szFilename, len);
+ return _taccess(szFilename, 0);
+}
+
+//////////////////////////////////////////////////////////
+// sets avatar
+
+INT_PTR GGPROTO::setmyavatar(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR *szFilename = (TCHAR*)lParam;
+
+ if (!db_get_b(NULL, m_szModuleName, GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS))
+ return -2;
+
+ if (szFilename == NULL) {
+ MessageBox(NULL,
+ TranslateT("To remove your Gadu-Gadu avatar, you must use the MojaGeneracja.pl website."),
+ m_tszUserName, MB_OK | MB_ICONINFORMATION);
+ return -1;
+ }
+
+ TCHAR szMyFilename[MAX_PATH];
+ getAvatarFilename(NULL, szMyFilename, SIZEOF(szMyFilename));
+ if ( _tcscmp(szFilename, szMyFilename) && !CopyFile(szFilename, szMyFilename, FALSE)) {
+ netlog("gg_setmyavatar(): Failed to set user avatar. File %s could not be created/overwritten.", szMyFilename);
+ return -1;
+ }
+
+ setAvatar(szMyFilename);
+ return 0;
+}
+
+//////////////////////////////////////////////////////////
+// gets protocol status message
+
+INT_PTR GGPROTO::getmyawaymsg(WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR res = 0;
+ char *szMsg;
+
+ EnterCriticalSection(&modemsg_mutex);
+ szMsg = getstatusmsg(wParam ? gg_normalizestatus(wParam) : m_iStatus);
+ if (isonline() && szMsg)
+ res = (lParam & SGMA_UNICODE) ? (INT_PTR)mir_a2u(szMsg) : (INT_PTR)mir_strdup(szMsg);
+ LeaveCriticalSection(&modemsg_mutex);
+ return res;
+}
+
+//////////////////////////////////////////////////////////
+// gets account manager GUI
+
+extern INT_PTR CALLBACK gg_acc_mgr_guidlgproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+INT_PTR GGPROTO::get_acc_mgr_gui(WPARAM wParam, LPARAM lParam)
+{
+ return (INT_PTR) CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, gg_acc_mgr_guidlgproc, (LPARAM)this);
+}
+
+//////////////////////////////////////////////////////////
+// leaves (terminates) conference
+
+INT_PTR GGPROTO::leavechat(WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if (hContact)
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0);
+
+ return 0;
+}
diff --git a/protocols/Gadu-Gadu/sessions.c b/protocols/Gadu-Gadu/sessions.cpp
index d5ea8b5577..1f8572258a 100644
--- a/protocols/Gadu-Gadu/sessions.c
+++ b/protocols/Gadu-Gadu/sessions.cpp
@@ -155,36 +155,37 @@ static HCURSOR hHandCursor = NULL;
static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
GGPROTO* gg = (GGPROTO*)GetWindowLongPtr(hwndDlg, DWLP_USER);
- switch (message)
- {
- case WM_INITDIALOG:
+ switch (message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+
+ gg = (GGPROTO*)lParam;
+ gg->hwndSessionsDlg = hwndDlg;
+
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
{
- GGPROTO* gg = (GGPROTO*)lParam;
TCHAR oldTitle[256], newTitle[256];
HANDLE hProtoAckEvent;
-
- SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
- TranslateDialogDefault(hwndDlg);
+
GetDlgItemText(hwndDlg, IDC_HEADERBAR, oldTitle, SIZEOF(oldTitle));
- mir_snprintf(newTitle, SIZEOF(newTitle), oldTitle, GG_PROTONAME);
+ mir_sntprintf(newTitle, SIZEOF(newTitle), oldTitle, gg->m_tszUserName);
SetDlgItemText(hwndDlg, IDC_HEADERBAR, newTitle);
WindowSetIcon(hwndDlg, "sessions");
- gg->hwndSessionsDlg = hwndDlg;
if (hHandCursor == NULL)
hHandCursor = LoadCursor(NULL, IDC_HAND);
hProtoAckEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_PROTOACK);
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)hProtoAckEvent);
-
+
ListView_SetExtendedListViewStyle(GetDlgItem(hwndDlg, IDC_SESSIONS), LVS_EX_FULLROWSELECT);
SendMessage(hwndDlg, WM_MULTILOGONINFO, 0, 0);
return TRUE;
}
- case HM_PROTOACK:
+ case HM_PROTOACK:
{
ACKDATA* ack = (ACKDATA*)lParam;
- if (!strcmp(ack->szModule, GG_PROTO) && !ack->hContact && ack->type == ACKTYPE_STATUS
+ if (!strcmp(ack->szModule, gg->m_szModuleName) && !ack->hContact && ack->type == ACKTYPE_STATUS
&& ack->result == ACKRESULT_SUCCESS && (ack->lParam == ID_STATUS_OFFLINE
|| (ack->hProcess == (HANDLE)ID_STATUS_CONNECTING && ack->lParam != ID_STATUS_OFFLINE
&& !ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_SESSIONS)))))
@@ -195,109 +196,109 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w
break;
}
- case WM_MULTILOGONINFO:
- gg_clearsessionslist(hwndDlg);
- gg_listsessions(gg, hwndDlg);
- break;
+ case WM_MULTILOGONINFO:
+ gg_clearsessionslist(hwndDlg);
+ gg_listsessions(gg, hwndDlg);
+ break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_SIGNOUTALL:
{
- case IDC_SIGNOUTALL:
+ HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
+ LVITEM lvi = {0};
+ int iCount = ListView_GetItemCount(hList), i;
+ lvi.mask = LVIF_PARAM;
+ for (i = 0; i < iCount; i++)
{
- HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
- LVITEM lvi = {0};
- int iCount = ListView_GetItemCount(hList), i;
- lvi.mask = LVIF_PARAM;
- for (i = 0; i < iCount; i++)
- {
- lvi.iItem = i;
- ListView_GetItem(hList, &lvi);
- EnterCriticalSection(&gg->sess_mutex);
- gg_multilogon_disconnect(gg->sess, *((gg_multilogon_id_t*)lvi.lParam));
- LeaveCriticalSection(&gg->sess_mutex);
- }
- break;
+ lvi.iItem = i;
+ ListView_GetItem(hList, &lvi);
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_multilogon_disconnect(gg->sess, *((gg_multilogon_id_t*)lvi.lParam));
+ LeaveCriticalSection(&gg->sess_mutex);
}
+ break;
}
- break;
+ }
+ break;
- case WM_NOTIFY:
- if (((LPNMHDR)lParam)->idFrom == IDC_SESSIONS)
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == IDC_SESSIONS)
+ {
+ switch (((LPNMHDR)lParam)->code)
{
- switch (((LPNMHDR)lParam)->code)
+ case NM_CUSTOMDRAW:
{
- case NM_CUSTOMDRAW:
+ LPNMLVCUSTOMDRAW nm = (LPNMLVCUSTOMDRAW)lParam;
+ switch (nm->nmcd.dwDrawStage)
{
- LPNMLVCUSTOMDRAW nm = (LPNMLVCUSTOMDRAW)lParam;
- switch (nm->nmcd.dwDrawStage)
+ case CDDS_PREPAINT:
+ if (ListView_GetItemCount(nm->nmcd.hdr.hwndFrom) == 0)
{
- case CDDS_PREPAINT:
- if (ListView_GetItemCount(nm->nmcd.hdr.hwndFrom) == 0)
- {
- const LPCTSTR szText = gg_isonline(gg)
- ? TranslateT("There are no active concurrent sessions for this account.")
- : TranslateT("You have to be logged in to view concurrent sessions.");
- RECT rc;
- HWND hwndHeader = ListView_GetHeader(nm->nmcd.hdr.hwndFrom);
- SIZE textSize;
- int textPosX;
- GetClientRect(nm->nmcd.hdr.hwndFrom, &rc);
- if (hwndHeader != NULL)
- {
- RECT rcHeader;
- GetClientRect(hwndHeader, &rcHeader);
- rc.top += rcHeader.bottom;
- }
- GetTextExtentPoint32(nm->nmcd.hdc, szText, lstrlen(szText), &textSize);
- textPosX = rc.left + (((rc.right - rc.left) - textSize.cx) / 2);
- ExtTextOut(nm->nmcd.hdc, textPosX, rc.top + textSize.cy, ETO_OPAQUE, &rc, szText, lstrlen(szText), NULL);
- }
- // FALL THROUGH
-
- case CDDS_ITEMPREPAINT:
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT , CDRF_NOTIFYSUBITEMDRAW);
- return TRUE;
-
- case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+ const LPCTSTR szText = gg->isonline()
+ ? TranslateT("There are no active concurrent sessions for this account.")
+ : TranslateT("You have to be logged in to view concurrent sessions.");
+ RECT rc;
+ HWND hwndHeader = ListView_GetHeader(nm->nmcd.hdr.hwndFrom);
+ SIZE textSize;
+ int textPosX;
+ GetClientRect(nm->nmcd.hdr.hwndFrom, &rc);
+ if (hwndHeader != NULL)
{
- RECT rc;
- ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc);
- if (nm->nmcd.hdr.idFrom == IDC_SESSIONS && nm->iSubItem == 3)
- {
- TCHAR szText[256];
- szText[0] = 0;
- ListView_GetItemText(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, szText, SIZEOF(szText));
- FillRect(nm->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
- SetTextColor(nm->nmcd.hdc, RGB(0, 0, 255));
- DrawText(nm->nmcd.hdc, szText, -1, &rc, DT_END_ELLIPSIS | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_TOP);
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT);
- return TRUE;
- }
- break;
+ RECT rcHeader;
+ GetClientRect(hwndHeader, &rcHeader);
+ rc.top += rcHeader.bottom;
}
+ GetTextExtentPoint32(nm->nmcd.hdc, szText, lstrlen(szText), &textSize);
+ textPosX = rc.left + (((rc.right - rc.left) - textSize.cx) / 2);
+ ExtTextOut(nm->nmcd.hdc, textPosX, rc.top + textSize.cy, ETO_OPAQUE, &rc, szText, lstrlen(szText), NULL);
}
- break;
- }
+ // FALL THROUGH
+
+ case CDDS_ITEMPREPAINT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT , CDRF_NOTIFYSUBITEMDRAW);
+ return TRUE;
- case NM_CLICK:
- if (IsOverAction(hwndDlg))
+ case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
{
- LPNMITEMACTIVATE nm = (LPNMITEMACTIVATE)lParam;
- LVITEM lvi = {0};
- lvi.mask = LVIF_PARAM;
- lvi.iItem = nm->iItem;
- ListView_GetItem(nm->hdr.hwndFrom, &lvi);
- EnterCriticalSection(&gg->sess_mutex);
- gg_multilogon_disconnect(gg->sess, *((gg_multilogon_id_t*)lvi.lParam));
- LeaveCriticalSection(&gg->sess_mutex);
+ RECT rc;
+ ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc);
+ if (nm->nmcd.hdr.idFrom == IDC_SESSIONS && nm->iSubItem == 3)
+ {
+ TCHAR szText[256];
+ szText[0] = 0;
+ ListView_GetItemText(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, szText, SIZEOF(szText));
+ FillRect(nm->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
+ SetTextColor(nm->nmcd.hdc, RGB(0, 0, 255));
+ DrawText(nm->nmcd.hdc, szText, -1, &rc, DT_END_ELLIPSIS | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_TOP);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT);
+ return TRUE;
+ }
+ break;
}
- break;
+ }
+ break;
+ }
+
+ case NM_CLICK:
+ if (IsOverAction(hwndDlg))
+ {
+ LPNMITEMACTIVATE nm = (LPNMITEMACTIVATE)lParam;
+ LVITEM lvi = {0};
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = nm->iItem;
+ ListView_GetItem(nm->hdr.hwndFrom, &lvi);
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_multilogon_disconnect(gg->sess, *((gg_multilogon_id_t*)lvi.lParam));
+ LeaveCriticalSection(&gg->sess_mutex);
}
+ break;
}
- break;
+ }
+ break;
- case WM_CONTEXTMENU:
+ case WM_CONTEXTMENU:
{
HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}, ptDlg = pt;
@@ -317,22 +318,23 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w
AppendMenu(hMenu, MFT_STRING, 10001, TranslateT("Copy Text"));
AppendMenu(hMenu, MFT_STRING, 10002, TranslateT("Whois"));
iSelection = TrackPopupMenu(hMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL);
- switch (iSelection)
- {
- case 10001:
+ switch (iSelection) {
+ case 10001:
{
- char szText[512], szClientName[256], szIP[64], szLoginTime[64];
+ TCHAR szText[512], szClientName[256], szIP[64], szLoginTime[64];
HGLOBAL hData;
- if (!OpenClipboard(hwndDlg)) break;
+ if (!OpenClipboard(hwndDlg))
+ break;
+
EmptyClipboard();
szClientName[0] = szIP[0] = szLoginTime[0] = 0;
ListView_GetItemText(hList, lvhti.iItem, 0, szClientName, SIZEOF(szClientName));
ListView_GetItemText(hList, lvhti.iItem, 1, szIP, SIZEOF(szIP));
ListView_GetItemText(hList, lvhti.iItem, 2, szLoginTime, SIZEOF(szLoginTime));
- mir_snprintf(szText, SIZEOF(szText), "%s\t%s\t%s", szClientName, szIP, szLoginTime);
- if ((hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(szText) + 1)) != NULL)
+ mir_sntprintf(szText, SIZEOF(szText), _T("%s\t%s\t%s"), szClientName, szIP, szLoginTime);
+ if ((hData = GlobalAlloc(GMEM_MOVEABLE, lstrlen(szText) + 1)) != NULL)
{
- lstrcpyA((char*)GlobalLock(hData), szText);
+ lstrcpy((TCHAR*)GlobalLock(hData), szText);
GlobalUnlock(hData);
SetClipboardData(CF_TEXT, hData);
}
@@ -340,13 +342,13 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w
break;
}
- case 10002:
+ case 10002:
{
- char szUrl[256], szIP[64];
+ TCHAR szUrl[256], szIP[64];
szIP[0] = 0;
ListView_GetItemText(hList, lvhti.iItem, 1, szIP, SIZEOF(szIP));
- mir_snprintf(szUrl, SIZEOF(szUrl), "http://whois.domaintools.com/%s", szIP);
- CallService(MS_UTILS_OPENURL, 1, (LPARAM)szUrl);
+ mir_sntprintf(szUrl, SIZEOF(szUrl), _T("http://whois.domaintools.com/%s"), szIP);
+ CallService(MS_UTILS_OPENURL, OUF_TCHAR, (LPARAM)szUrl);
break;
}
}
@@ -355,12 +357,12 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w
break;
}
- case WM_GETMINMAXINFO:
- ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = 620;
- ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = 220;
- return 0;
+ case WM_GETMINMAXINFO:
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = 620;
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = 220;
+ return 0;
- case WM_SIZE:
+ case WM_SIZE:
{
UTILRESIZEDIALOG urd = {0};
urd.cbSize = sizeof(urd);
@@ -372,20 +374,20 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w
return 0;
}
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT && IsOverAction(hwndDlg))
- {
- SetCursor(hHandCursor);
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
- return TRUE;
- }
- break;
+ case WM_SETCURSOR:
+ if (LOWORD(lParam) == HTCLIENT && IsOverAction(hwndDlg))
+ {
+ SetCursor(hHandCursor);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
- case WM_CLOSE:
- DestroyWindow(hwndDlg);
- break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
- case WM_DESTROY:
+ case WM_DESTROY:
{
HANDLE hProtoAckEvent = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
if (hProtoAckEvent) UnhookEvent(hProtoAckEvent);
@@ -397,33 +399,33 @@ static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM w
return FALSE;
}
-INT_PTR gg_sessions_view(GGPROTO* gg, WPARAM wParam, LPARAM lParam)
+INT_PTR GGPROTO::sessions_view(WPARAM wParam, LPARAM lParam)
{
- if (gg->hwndSessionsDlg && IsWindow(gg->hwndSessionsDlg))
+ if (hwndSessionsDlg && IsWindow(hwndSessionsDlg))
{
- ShowWindow(gg->hwndSessionsDlg, SW_SHOWNORMAL);
- SetForegroundWindow(gg->hwndSessionsDlg);
- SetFocus(gg->hwndSessionsDlg);
+ ShowWindow(hwndSessionsDlg, SW_SHOWNORMAL);
+ SetForegroundWindow(hwndSessionsDlg);
+ SetFocus(hwndSessionsDlg);
}
else
- CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_SESSIONS), NULL, gg_sessions_viewdlg, (LPARAM)gg);
+ CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_SESSIONS), NULL, gg_sessions_viewdlg, (LPARAM)this);
return 0;
}
-void gg_sessions_updatedlg(GGPROTO* gg)
+void GGPROTO::sessions_updatedlg()
{
- if (gg->hwndSessionsDlg && IsWindow(gg->hwndSessionsDlg))
- SendMessage(gg->hwndSessionsDlg, WM_MULTILOGONINFO, 0, 0);
+ if (hwndSessionsDlg && IsWindow(hwndSessionsDlg))
+ SendMessage(hwndSessionsDlg, WM_MULTILOGONINFO, 0, 0);
}
-BOOL gg_sessions_closedlg(GGPROTO* gg)
+BOOL GGPROTO::sessions_closedlg()
{
- if (gg->hwndSessionsDlg && IsWindow(gg->hwndSessionsDlg))
- return PostMessage(gg->hwndSessionsDlg, WM_CLOSE, 0, 0);
+ if (hwndSessionsDlg && IsWindow(hwndSessionsDlg))
+ return PostMessage(hwndSessionsDlg, WM_CLOSE, 0, 0);
return FALSE;
}
-void gg_sessions_menus_init(GGPROTO* gg, HGENMENU hRoot)
+void GGPROTO::sessions_menus_init(HGENMENU hRoot)
{
CLISTMENUITEM mi = {0};
char service[64];
@@ -432,9 +434,9 @@ void gg_sessions_menus_init(GGPROTO* gg, HGENMENU hRoot)
mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTHANDLE | CMIF_TCHAR;
mi.hParentMenu = hRoot;
- mir_snprintf(service, sizeof(service), GGS_CONCUR_SESS, GG_PROTO);
- CreateProtoServiceFunction(service, gg_sessions_view, gg);
- if (gg->hMenuRoot)
+ mir_snprintf(service, sizeof(service), GGS_CONCUR_SESS, m_szModuleName);
+ createProtoService(service, &GGPROTO::sessions_view);
+ if (hMenuRoot)
mi.position = 2050000001;
else
mi.position = 200003;
diff --git a/protocols/Gadu-Gadu/token.c b/protocols/Gadu-Gadu/token.cpp
index 378766ef4a..d2946c12ef 100644
--- a/protocols/Gadu-Gadu/token.c
+++ b/protocols/Gadu-Gadu/token.cpp
@@ -57,7 +57,7 @@ INT_PTR CALLBACK gg_tokendlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l
{
case IDOK:
{
- GetDlgItemText(hwndDlg, IDC_TOKEN, dat->val, sizeof(dat->val));
+ GetDlgItemTextA(hwndDlg, IDC_TOKEN, dat->val, sizeof(dat->val));
EndDialog(hwndDlg, IDOK);
break;
}
@@ -74,7 +74,7 @@ INT_PTR CALLBACK gg_tokendlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l
RECT rc; GetClientRect(GetDlgItem(hwndDlg, IDC_WHITERECT), &rc);
FillRect(hdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH));
- if(dat && dat->hBitmap)
+ if (dat && dat->hBitmap)
{
HDC hdcBmp = NULL;
int nWidth, nHeight;
@@ -83,7 +83,7 @@ INT_PTR CALLBACK gg_tokendlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l
GetObject(dat->hBitmap, sizeof(bmp), &bmp);
nWidth = bmp.bmWidth; nHeight = bmp.bmHeight;
- if(hdcBmp = CreateCompatibleDC(hdc))
+ if (hdcBmp = CreateCompatibleDC(hdc))
{
SelectObject(hdcBmp, dat->hBitmap);
SetStretchBltMode(hdc, HALFTONE);
@@ -104,7 +104,7 @@ INT_PTR CALLBACK gg_tokendlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM l
////////////////////////////////////////////////////////////////////////////////
// Gets GG token
-int gg_gettoken(GGPROTO *gg, GGTOKEN *token)
+int GGPROTO::gettoken(GGTOKEN *token)
{
struct gg_http *h = NULL;
struct gg_token *t = NULL;
@@ -115,30 +115,18 @@ int gg_gettoken(GGPROTO *gg, GGTOKEN *token)
strcpy(token->id, "");
strcpy(token->val, "");
- if (!(h = gg_token(0)) || gg_token_watch_fd(h) || h->state == GG_STATE_ERROR || h->state != GG_STATE_DONE)
- {
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Token retrieval failed because of error:\n\t%s"), http_error_string(h ? h->error : 0));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
+ if (!(h = gg_token(0)) || gg_token_watch_fd(h) || h->state == GG_STATE_ERROR || h->state != GG_STATE_DONE) {
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Token retrieval failed because of error:\n\t%S"), http_error_string(h ? h->error : 0));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
gg_free_pubdir(h);
return FALSE;
}
- if (!(t = (struct gg_token *)h->data) || (!h->body))
- {
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Token retrieval failed because of error:\n\t%s"), http_error_string(h ? h->error : 0));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
+ if (!(t = (struct gg_token *)h->data) || (!h->body)) {
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Token retrieval failed because of error:\n\t%S"), http_error_string(h ? h->error : 0));
+ MessageBox(NULL, error, m_tszUserName, MB_OK | MB_ICONSTOP);
gg_free_pubdir(h);
return FALSE;
}
@@ -151,23 +139,18 @@ int gg_gettoken(GGPROTO *gg, GGTOKEN *token)
// Load bitmap
memio.iLen = h->body_size;
memio.pBuf = (void *)h->body;
- memio.fif = -1; /* detect */
+ memio.fif = FIF_UNKNOWN; /* detect */
memio.flags = 0;
dat.hBitmap = (HBITMAP) CallService(MS_IMG_LOADFROMMEM, (WPARAM) &memio, 0);
- if(dat.hBitmap == NULL)
+ if (dat.hBitmap == NULL)
{
- MessageBox(
- NULL,
- Translate("Could not load token image."),
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
+ MessageBox(NULL, TranslateT("Could not load token image."), m_tszUserName, MB_OK | MB_ICONSTOP);
gg_free_pubdir(h);
return FALSE;
}
// Load token dialog
- if(DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_TOKEN), NULL, gg_tokendlgproc, (LPARAM)&dat) == IDCANCEL)
+ if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_TOKEN), NULL, gg_tokendlgproc, (LPARAM)&dat) == IDCANCEL)
return FALSE;
// Fillup patterns
diff --git a/protocols/Gadu-Gadu/userutils.c b/protocols/Gadu-Gadu/userutils.cpp
index 721e4d32cf..c8476f821d 100644
--- a/protocols/Gadu-Gadu/userutils.c
+++ b/protocols/Gadu-Gadu/userutils.cpp
@@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
// Create New Account : Proc
+
void *gg_doregister(GGPROTO *gg, char *newPass, char *newEmail)
{
// Connection handles
@@ -30,46 +31,43 @@ void *gg_doregister(GGPROTO *gg, char *newPass, char *newEmail)
GGTOKEN token;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_doregister(): Starting.");
+ gg->netlog("gg_doregister(): Starting.");
#endif
if (!newPass || !newEmail) return NULL;
// Load token
- if (!gg_gettoken(gg, &token)) return NULL;
+ if (!gg->gettoken(&token)) return NULL;
- if (!(h = gg_register3(newEmail, newPass, token.id, token.val, 0)) || !(s = h->data) || !s->success || !s->uin)
+ if (!(h = gg_register3(newEmail, newPass, token.id, token.val, 0)) || !(s = (gg_pubdir*)h->data) || !s->success || !s->uin)
{
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Cannot register new account because of error:\n\t%s"),
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Cannot register new account because of error:\n\t%S"),
(h && !s) ? http_error_string(h ? h->error : 0) :
(s ? Translate("Registration rejected") : strerror(errno)));
MessageBox(
NULL,
error,
- GG_PROTONAME,
+ gg->m_tszUserName,
MB_OK | MB_ICONSTOP
);
- gg_netlog(gg, "gg_doregister(): Cannot register because of \"%s\".", strerror(errno));
+ gg->netlog("gg_doregister(): Cannot register because of \"%s\".", strerror(errno));
}
else
{
- DBWriteContactSettingDword(NULL, GG_PROTO, GG_KEY_UIN, s->uin);
+ db_set_w(NULL, gg->m_szModuleName, GG_KEY_UIN, s->uin);
CallService(MS_DB_CRYPT_ENCODESTRING, strlen(newPass) + 1, (LPARAM) newPass);
- gg_checknewuser(gg, s->uin, newPass);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, newPass);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, newEmail);
+ gg->checknewuser(s->uin, newPass);
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, newPass);
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, newEmail);
gg_pubdir_free(h);
- gg_netlog(gg, "gg_doregister(): Account registration succesful.");
- MessageBox(
- NULL,
- Translate("You have registered new account.\nPlease fill up your personal details in \"M->View/Change My Details...\""),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
+ gg->netlog("gg_doregister(): Account registration succesful.");
+ MessageBox( NULL,
+ TranslateT("You have registered new account.\nPlease fill up your personal details in \"M->View/Change My Details...\""),
+ gg->m_tszUserName, MB_OK | MB_ICONINFORMATION);
}
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_doregister(): End.");
+ gg->netlog("gg_doregister(): End.");
#endif
return NULL;
@@ -85,43 +83,33 @@ void *gg_dounregister(GGPROTO *gg, uin_t uin, char *password)
GGTOKEN token;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dounregister(): Starting.");
+ gg->netlog("gg_dounregister(): Starting.");
#endif
if (!uin || !password) return NULL;
// Load token
- if (!gg_gettoken(gg, &token)) return NULL;
+ if (!gg->gettoken(&token)) return NULL;
- if (!(h = gg_unregister3(uin, password, token.id, token.val, 0)) || !(s = h->data) || !s->success || s->uin != uin)
+ if (!(h = gg_unregister3(uin, password, token.id, token.val, 0)) || !(s = (gg_pubdir*)h->data) || !s->success || s->uin != uin)
{
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Your account cannot be removed because of error:\n\t%s"),
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Your account cannot be removed because of error:\n\t%S"),
(h && !s) ? http_error_string(h ? h->error : 0) :
(s ? Translate("Bad number or password") : strerror(errno)));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_dounregister(): Cannot remove account because of \"%s\".", strerror(errno));
+ MessageBox(NULL, error, gg->m_tszUserName, MB_OK | MB_ICONSTOP);
+ gg->netlog("gg_dounregister(): Cannot remove account because of \"%s\".", strerror(errno));
}
else
{
gg_pubdir_free(h);
- DBDeleteContactSetting(NULL, GG_PROTO, GG_KEY_PASSWORD);
- DBDeleteContactSetting(NULL, GG_PROTO, GG_KEY_UIN);
- gg_netlog(gg, "gg_dounregister(): Account %d has been removed.", uin);
- MessageBox(
- NULL,
- Translate("Your account has been removed."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
+ db_unset(NULL, gg->m_szModuleName, GG_KEY_PASSWORD);
+ db_unset(NULL, gg->m_szModuleName, GG_KEY_UIN);
+ gg->netlog("gg_dounregister(): Account %d has been removed.", uin);
+ MessageBox(NULL, TranslateT("Your account has been removed."), gg->m_tszUserName, MB_OK | MB_ICONINFORMATION);
}
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dounregister(): End.");
+ gg->netlog("gg_dounregister(): End.");
#endif
return NULL;
@@ -129,6 +117,7 @@ void *gg_dounregister(GGPROTO *gg, uin_t uin, char *password)
////////////////////////////////////////////////////////////////////////////////
// Change Password Page : Proc
+
void *gg_dochpass(GGPROTO *gg, uin_t uin, char *password, char *newPass)
{
// Readup email
@@ -139,49 +128,40 @@ void *gg_dochpass(GGPROTO *gg, uin_t uin, char *password, char *newPass)
GGTOKEN token;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dochpass(): Starting.");
+ gg->netlog("gg_dochpass(): Starting.");
#endif
if (!uin || !password || !newPass) return NULL;
- if (!DBGetContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, &dbv_email))
- {
+ if (!db_get_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, &dbv_email, DBVT_ASCIIZ))
+ {
strncpy(email, dbv_email.pszVal, sizeof(email));
- DBFreeVariant(&dbv_email);
- }
-
+ DBFreeVariant(&dbv_email);
+ }
+
// Load token
- if (!gg_gettoken(gg, &token)) return NULL;
+ if (!gg->gettoken(&token))
+ return NULL;
- if (!(h = gg_change_passwd4(uin, email, password, newPass, token.id, token.val, 0)) || !(s = h->data) || !s->success)
+ if (!(h = gg_change_passwd4(uin, email, password, newPass, token.id, token.val, 0)) || !(s = (gg_pubdir*)h->data) || !s->success)
{
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Your password cannot be changed because of error:\n\t%s"),
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Your password cannot be changed because of error:\n\t%S"),
(h && !s) ? http_error_string(h ? h->error : 0) :
(s ? Translate("Invalid data entered") : strerror(errno)));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_dochpass(): Cannot change password because of \"%s\".", strerror(errno));
+ MessageBox(NULL, error, gg->m_tszUserName, MB_OK | MB_ICONSTOP);
+ gg->netlog("gg_dochpass(): Cannot change password because of \"%s\".", strerror(errno));
}
else
{
gg_pubdir_free(h);
CallService(MS_DB_CRYPT_ENCODESTRING, strlen(newPass) + 1, (LPARAM) newPass);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_PASSWORD, newPass);
- gg_netlog(gg, "gg_dochpass(): Password change succesful.");
- MessageBox(
- NULL,
- Translate("Your password has been changed."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_PASSWORD, newPass);
+ gg->netlog("gg_dochpass(): Password change succesful.");
+ MessageBox(NULL, TranslateT("Your password has been changed."), gg->m_tszUserName, MB_OK | MB_ICONINFORMATION);
}
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_dochpass(): End.");
+ gg->netlog("gg_dochpass(): End.");
#endif
return NULL;
@@ -189,6 +169,7 @@ void *gg_dochpass(GGPROTO *gg, uin_t uin, char *password, char *newPass)
////////////////////////////////////////////////////////////////////////////////
// Change E-mail Page : Proc
+
void *gg_dochemail(GGPROTO *gg, uin_t uin, char *password, char *email, char *newEmail)
{
// Connection handles
@@ -197,42 +178,31 @@ void *gg_dochemail(GGPROTO *gg, uin_t uin, char *password, char *email, char *ne
GGTOKEN token;
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_doemail(): Starting.");
+ gg->netlog("gg_doemail(): Starting.");
#endif
if (!uin || !email || !newEmail) return NULL;
// Load token
- if (!gg_gettoken(gg, &token)) return NULL;
+ if (!gg->gettoken(&token)) return NULL;
- if (!(h = gg_change_passwd4(uin, newEmail, password, password, token.id, token.val, 0)) || !(s = h->data) || !s->success)
+ if (!(h = gg_change_passwd4(uin, newEmail, password, password, token.id, token.val, 0)) || !(s = (gg_pubdir*)h->data) || !s->success)
{
- char error[128];
- mir_snprintf(error, sizeof(error), Translate("Your e-mail cannot be changed because of error:\n\t%s"),
- (h && !s) ? http_error_string(h ? h->error : 0) :
- (s ? Translate("Bad old e-mail or password") : strerror(errno)));
- MessageBox(
- NULL,
- error,
- GG_PROTONAME,
- MB_OK | MB_ICONSTOP
- );
- gg_netlog(gg, "gg_dochpass(): Cannot change e-mail because of \"%s\".", strerror(errno));
+ TCHAR error[128];
+ mir_sntprintf(error, SIZEOF(error), TranslateT("Your e-mail cannot be changed because of error:\n\t%s"),
+ (h && !s) ? http_error_string(h ? h->error : 0) : (s ? Translate("Bad old e-mail or password") : strerror(errno)));
+ MessageBox(NULL, error, gg->m_tszUserName, MB_OK | MB_ICONSTOP);
+ gg->netlog("gg_dochpass(): Cannot change e-mail because of \"%s\".", strerror(errno));
}
else
{
gg_pubdir_free(h);
- DBWriteContactSettingString(NULL, GG_PROTO, GG_KEY_EMAIL, newEmail);
- gg_netlog(gg, "gg_doemail(): E-mail change succesful.");
- MessageBox(
- NULL,
- Translate("Your e-mail has been changed."),
- GG_PROTONAME,
- MB_OK | MB_ICONINFORMATION
- );
+ db_set_s(NULL, gg->m_szModuleName, GG_KEY_EMAIL, newEmail);
+ gg->netlog("gg_doemail(): E-mail change succesful.");
+ MessageBox(NULL, TranslateT("Your e-mail has been changed."), gg->m_tszUserName, MB_OK | MB_ICONINFORMATION);
}
#ifdef DEBUGMODE
- gg_netlog(gg, "gg_doemail(): End.");
+ gg->netlog("gg_doemail(): End.");
#endif
return NULL;
@@ -251,7 +221,7 @@ INT_PTR CALLBACK gg_userutildlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
WindowSetIcon(hwndDlg, "settings");
dat = (GGUSERUTILDLGDATA *)lParam;
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
- if (dat) SetDlgItemText(hwndDlg, IDC_EMAIL, dat->email); // Readup email
+ if (dat) SetDlgItemTextA(hwndDlg, IDC_EMAIL, dat->email); // Readup email
return TRUE;
case WM_COMMAND:
@@ -263,8 +233,8 @@ INT_PTR CALLBACK gg_userutildlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
{
char pass[128], cpass[128];
BOOL enable;
- GetDlgItemText(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
- GetDlgItemText(hwndDlg, IDC_CPASSWORD, cpass, sizeof(cpass));
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
+ GetDlgItemTextA(hwndDlg, IDC_CPASSWORD, cpass, sizeof(cpass));
enable = strlen(pass) && strlen(cpass) && !strcmp(cpass, pass);
if (dat && dat->mode == GG_USERUTIL_REMOVE)
EnableWindow(GetDlgItem(hwndDlg, IDOK), IsDlgButtonChecked(hwndDlg, IDC_CONFIRM) ? enable : FALSE);
@@ -276,9 +246,9 @@ INT_PTR CALLBACK gg_userutildlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
case IDOK:
{
char pass[128], cpass[128], email[128];
- GetDlgItemText(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
- GetDlgItemText(hwndDlg, IDC_CPASSWORD, cpass, sizeof(cpass));
- GetDlgItemText(hwndDlg, IDC_EMAIL, email, sizeof(email));
+ GetDlgItemTextA(hwndDlg, IDC_PASSWORD, pass, sizeof(pass));
+ GetDlgItemTextA(hwndDlg, IDC_CPASSWORD, cpass, sizeof(cpass));
+ GetDlgItemTextA(hwndDlg, IDC_EMAIL, email, sizeof(email));
EndDialog(hwndDlg, IDOK);
// Check dialog box mode
@@ -305,3 +275,50 @@ INT_PTR CALLBACK gg_userutildlgproc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
}
return FALSE;
}
+
+//////////////////////////////////////////////////////////
+// Hooks protocol event
+
+HANDLE GGPROTO::hookProtoEvent(const char* szEvent, GGEventFunc handler)
+{
+ return ::HookEventObj(szEvent, ( MIRANDAHOOKOBJ )*( void** )&handler, this);
+}
+
+//////////////////////////////////////////////////////////
+// Adds a new protocol specific service function
+
+void GGPROTO::createProtoService(const char* szService, GGServiceFunc serviceProc)
+{
+ char str[MAXMODULELABELLENGTH];
+ mir_snprintf(str, sizeof(str), "%s%s", m_szModuleName, szService);
+ CreateServiceFunctionObj(str, (MIRANDASERVICEOBJ)*( void** )&serviceProc, this);
+}
+
+//////////////////////////////////////////////////////////
+// Forks a thread
+
+void GGPROTO::forkthread(GGThreadFunc pFunc, void *param)
+{
+ UINT threadId;
+ CloseHandle( mir_forkthreadowner((pThreadFuncOwner)*(void**)&pFunc, this, param, &threadId));
+}
+
+//////////////////////////////////////////////////////////
+// Forks a thread and returns a pseudo handle for it
+
+HANDLE GGPROTO::forkthreadex(GGThreadFunc pFunc, void *param, UINT *threadId)
+{
+ return mir_forkthreadowner((pThreadFuncOwner)*(void**)&pFunc, this, param, threadId);
+}
+
+//////////////////////////////////////////////////////////
+// Wait for thread to stop
+
+void GGPROTO::threadwait(GGTHREAD *thread)
+{
+ if (!thread->hThread) return;
+ while (WaitForSingleObjectEx(thread->hThread, INFINITE, TRUE) != WAIT_OBJECT_0);
+ CloseHandle(thread->hThread);
+ ZeroMemory(thread, sizeof(GGTHREAD));
+}
+