summaryrefslogtreecommitdiff
path: root/MySpace/server_con.cpp
diff options
context:
space:
mode:
authorsje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2007-07-03 06:26:19 +0000
committersje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2007-07-03 06:26:19 +0000
commit6ad2fdede0ae25dc0d56b5e45f6b9aa876e93b68 (patch)
tree338cd3a33a281b5f8372908f9b2ffb280dd611f2 /MySpace/server_con.cpp
parent3211838af8942e88c53fb775ccd1a2524049592e (diff)
don't strip links in <a> tags
get avatars! woohoo :) git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@248 4f64403b-2f21-0410-a795-97e2b3489a10
Diffstat (limited to 'MySpace/server_con.cpp')
-rw-r--r--MySpace/server_con.cpp270
1 files changed, 265 insertions, 5 deletions
diff --git a/MySpace/server_con.cpp b/MySpace/server_con.cpp
index baf506f..5131655 100644
--- a/MySpace/server_con.cpp
+++ b/MySpace/server_con.cpp
@@ -8,6 +8,7 @@
#include <malloc.h>
#include <ctime>
+#include <cstdlib>
#define SERVER_READ_BUFFER_SIZE (1024 * 32)
@@ -33,6 +34,19 @@ int sesskey = 0, req_id = 1, my_uid = 0;
int signon_status = ID_STATUS_ONLINE;
char signon_status_msg[512] = {0};
+bool WriteData(char *fn, int fn_size, char *data, int data_size) {
+ // prepend dir to filename & create dir?
+ HANDLE hSaveFile = CreateFileA(fn, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if(hSaveFile == INVALID_HANDLE_VALUE) return false;
+
+ unsigned long bytes_written = 0;
+ bool ret = false;
+ if(WriteFile(hSaveFile, data, data_size, &bytes_written, NULL) == TRUE) ret = true;
+
+ CloseHandle(hSaveFile);
+ return ret;
+}
+
int stat_mir_to_myspace(int mir_status) {
switch(mir_status) {
case ID_STATUS_INVISIBLE: return 0;
@@ -384,6 +398,8 @@ void __cdecl ServerThreadFunc(void*) {
msg_status.add_string("locstring", "");
SendMessage(msg_status);
+ LookupUID(my_uid);
+
/*
// set login time?
Dictionary ld;
@@ -515,10 +531,17 @@ void __cdecl ServerThreadFunc(void*) {
mpsr.psr.email = email;
mpsr.uid = uid;
- HANDLE hContact = FindContact(uid);
- if(hContact) {
- if(mpsr.psr.nick) DBWriteContactSettingStringUtf(hContact, MODULE, "Nick", mpsr.psr.nick);
- if(mpsr.psr.email) DBWriteContactSettingStringUtf(hContact, MODULE, "email", mpsr.psr.email);
+ HANDLE hContact = 0;
+ hContact = FindContact(uid);
+ if(hContact || uid == my_uid) {
+ if(mpsr.psr.nick) {
+ DBWriteContactSettingStringUtf(hContact, MODULE, "Nick", mpsr.psr.nick);
+ if(uid == my_uid) DBWriteContactSettingStringUtf(0, MODULE, "Nick", mpsr.psr.nick);
+ }
+ if(mpsr.psr.email) {
+ DBWriteContactSettingStringUtf(hContact, MODULE, "email", mpsr.psr.email);
+ if(uid == my_uid) DBWriteContactSettingStringUtf(0, MODULE, "email", mpsr.psr.email);
+ }
char band[256], song[256];
band[0] = song[0] = 0;
@@ -526,8 +549,25 @@ void __cdecl ServerThreadFunc(void*) {
KeyValue &kv = i.val();
if(strcmp(kv.first.text, "Gender") == 0) {
DBWriteContactSettingByte(hContact, MODULE, "Gender", kv.second.text[0]);
+ if(uid == my_uid) DBWriteContactSettingByte(0, MODULE, "Gender", kv.second.text[0]);
+ } else if(strcmp(kv.first.text, "ImageURL") == 0) {
+ DBVARIANT dbv;
+ if(!DBGetContactSettingStringUtf(hContact, MODULE, "ImageURL", &dbv)) {
+ if(strcmp(kv.first.text, dbv.pszVal) != 0) {
+ // avatar changed
+ DBDeleteContactSetting(hContact, MODULE, "AvatarFilename");
+ if(uid == my_uid) DBDeleteContactSetting(0, MODULE, "AvatarFilename");
+ DBWriteContactSettingStringUtf(hContact, MODULE, kv.first.text, kv.second.text);
+ if(uid == my_uid) DBWriteContactSettingStringUtf(0, MODULE, kv.first.text, kv.second.text);
+ }
+ DBFreeVariant(&dbv);
+ }else {
+ DBWriteContactSettingStringUtf(hContact, MODULE, kv.first.text, kv.second.text);
+ if(uid == my_uid) DBWriteContactSettingStringUtf(0, MODULE, kv.first.text, kv.second.text);
+ }
} else {
DBWriteContactSettingStringUtf(hContact, MODULE, kv.first.text, kv.second.text);
+ if(uid == my_uid) DBWriteContactSettingStringUtf(0, MODULE, kv.first.text, kv.second.text);
if(strcmp(kv.first.text, "BandName") == 0) strncpy(band, kv.second.text, 256);
if(strcmp(kv.first.text, "SongName") == 0) strncpy(song, kv.second.text, 256);
}
@@ -536,13 +576,13 @@ void __cdecl ServerThreadFunc(void*) {
char listenTo[512];
mir_snprintf(listenTo, 512, "%s/%s", band, song);
DBWriteContactSettingStringUtf(hContact, MODULE, "ListeningTo", listenTo);
+ if(uid == my_uid) DBWriteContactSettingStringUtf(0, MODULE, "ListeningTo", listenTo);
}
ProtoBroadcastAck(MODULE, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1, 0);
}
ProtoBroadcastAck(MODULE, 0, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)req, (LPARAM)&mpsr);
-
}
ProtoBroadcastAck(MODULE, 0, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)req, 0);
}
@@ -663,3 +703,223 @@ void SetServerStatusMessage(char *msg) {
QueueUserAPC(sttMainThreadStatusMessageCallback, mainThread, (ULONG_PTR)(msg ? strdup(msg): 0));
}
+int NetlibHttpRecvChunkHeader(HANDLE hConnection, BOOL first)
+{
+ char data[32], *peol1;
+
+ int recvResult = Netlib_Recv(hConnection, data, 31, MSG_PEEK);
+ data[recvResult] = 0;
+
+ peol1 = strstr(data, "\r\n");
+ if (peol1 != NULL)
+ {
+ char *peol2 = first ? peol1 : strstr(peol1 + 2, "\r\n");
+ if (peol2 != NULL)
+ {
+ Netlib_Recv(hConnection, data, peol2 - data + 2, 0);
+ return atoi(first ? data : peol1+2);
+ }
+ }
+
+ return SOCKET_ERROR;
+}
+
+NETLIBHTTPREQUEST* NetlibHttpRecv(HANDLE hConnection, DWORD hflags, DWORD dflags)
+{
+ int dataLen = -1, i, chunkhdr;
+ int chunked = FALSE;
+
+ NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_RECVHTTPHEADERS, (WPARAM)hConnection, hflags);
+ if (nlhrReply==NULL)
+ return NULL;
+
+ for(i=0;i<nlhrReply->headersCount;i++)
+ {
+ if(!lstrcmpiA(nlhrReply->headers[i].szName, "Content-Length"))
+ dataLen = atoi(nlhrReply->headers[i].szValue);
+
+ if(!lstrcmpiA(nlhrReply->headers[i].szName, "Transfer-Encoding") &&
+ !lstrcmpiA(nlhrReply->headers[i].szValue, "chunked"))
+ {
+ chunked = TRUE;
+ chunkhdr = i;
+ break;
+ }
+ }
+
+ if (nlhrReply->resultCode >= 200 && dataLen != 0)
+ {
+ int recvResult, chunksz = 0;
+ int dataBufferAlloced = dataLen + 1;
+
+ if (chunked)
+ {
+ chunksz = NetlibHttpRecvChunkHeader(hConnection, TRUE);
+ if (chunksz == SOCKET_ERROR)
+ {
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
+ return NULL;
+ }
+ dataLen = dataBufferAlloced = chunksz;
+ }
+
+ nlhrReply->pData = (char *)mir_realloc(nlhrReply->pData, dataBufferAlloced);
+
+ do {
+ for(;;) {
+ if(dataBufferAlloced-nlhrReply->dataLength<1024 && dataLen == -1) {
+ dataBufferAlloced+=2048;
+ nlhrReply->pData=(char *)mir_realloc(nlhrReply->pData,dataBufferAlloced);
+ if(nlhrReply->pData==NULL) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0,(LPARAM)nlhrReply);
+ return NULL;
+ }
+ }
+ recvResult=Netlib_Recv(hConnection,nlhrReply->pData+nlhrReply->dataLength,
+ dataBufferAlloced-nlhrReply->dataLength-1, dflags);
+
+ if(recvResult==0) break;
+ if(recvResult==SOCKET_ERROR) {
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0,(LPARAM)nlhrReply);
+ return NULL;
+ }
+ nlhrReply->dataLength += recvResult;
+
+ if (dataLen > -1 && nlhrReply->dataLength >= dataLen)
+ break;
+ }
+
+ if (chunked)
+ {
+ chunksz = NetlibHttpRecvChunkHeader(hConnection, FALSE);
+ if (chunksz == SOCKET_ERROR)
+ {
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
+ return NULL;
+ }
+ dataLen += chunksz;
+ dataBufferAlloced += chunksz;
+
+ nlhrReply->pData = (char *)mir_realloc(nlhrReply->pData, dataBufferAlloced);
+ }
+ } while (chunksz != 0);
+
+ nlhrReply->pData[nlhrReply->dataLength]='\0';
+ }
+
+ if (chunked)
+ {
+ nlhrReply->headers[chunkhdr].szName = (char *)mir_realloc(nlhrReply->headers[chunkhdr].szName, 16);
+ lstrcpyA(nlhrReply->headers[chunkhdr].szName, "Content-Length");
+
+ nlhrReply->headers[chunkhdr].szValue = (char *)mir_realloc(nlhrReply->headers[chunkhdr].szValue, 16);
+ mir_snprintf(nlhrReply->headers[chunkhdr].szValue, 16, "%u", nlhrReply->dataLength);
+ }
+
+ return nlhrReply;
+}
+
+typedef struct {
+ HANDLE hContact;
+ char *url;
+} av_dl_info;
+
+void __cdecl sttDownloadAvatar(void *param) {
+ av_dl_info *info = (av_dl_info *)param;
+
+ NETLIBHTTPREQUEST req = {0};
+ req.cbSize = sizeof(req);
+ req.requestType = REQUEST_GET;
+ req.szUrl = info->url;
+ req.flags = 0;
+ NETLIBHTTPREQUEST *nlhrReply = 0;
+
+ ProtoBroadcastAck(MODULE,info->hContact, ACKTYPE_AVATAR, ACKRESULT_CONNECTING, 0, 0);
+
+ HANDLE hConnection = 0;
+ {
+ NETLIBOPENCONNECTION nloc={0};
+ char szHost[128];
+ char *ppath,*phost,*pcolon;
+
+ phost=strstr(info->url,"://");
+ if(phost==NULL) phost=info->url;
+ else phost+=3;
+ lstrcpynA(szHost,phost,sizeof(szHost));
+ ppath=strchr(szHost,'/');
+ if(ppath) *ppath='\0';
+ nloc.cbSize=sizeof(nloc);
+ nloc.szHost=szHost;
+ pcolon=strrchr(szHost,':');
+ if(pcolon) {
+ *pcolon='\0';
+ nloc.wPort=(WORD)atoi(pcolon+1);
+ }
+ else nloc.wPort=80;
+ nloc.flags=NLOCF_HTTP;
+ hConnection=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser,(LPARAM)&nloc);
+ if(hConnection==NULL) {
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_FAILED,0, 0);
+ goto free_and_exit;
+ }
+ }
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_CONNECTED, 0, 0);
+
+ if(!CallService(MS_NETLIB_SENDHTTPREQUEST, (WPARAM)hConnection, (LPARAM)&req)) {
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_FAILED,0, 0);
+ goto free_and_exit;
+ }
+
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_SENTREQUEST, 0, 0);
+
+ int dflags = (req.flags&NLHRF_DUMPASTEXT?MSG_DUMPASTEXT:0) |
+ (req.flags&NLHRF_NODUMP?MSG_NODUMP:(req.flags&NLHRF_DUMPPROXY?MSG_DUMPPROXY:0));
+
+ nlhrReply = NetlibHttpRecv(hConnection, 0, dflags);
+
+ Netlib_CloseHandle(hConnection);
+
+ if(nlhrReply) {
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_DATA, 0, 0);
+
+ char *ext = strrchr(info->url, '.');
+
+ // write file
+ int uid = DBGetContactSettingDword(info->hContact, MODULE, "UID", 0);
+
+ char fn[MAX_PATH];
+ char buff[128];
+ mir_snprintf(fn, MAX_PATH, "%s_%s.%s", _itoa(uid, buff, 10), _itoa((int)time(0), buff, 10), ext);
+
+ WriteData(fn, MAX_PATH, nlhrReply->pData, nlhrReply->dataLength);
+
+ PROTO_AVATAR_INFORMATION AI = {0};
+ AI.cbSize = sizeof(PROTO_AVATAR_INFORMATION);
+ AI.hContact = info->hContact;
+ strncpy(AI.filename, fn, MAX_PATH);
+ AI.format =
+ (stricmp(ext, ".png") ? PA_FORMAT_PNG :
+ (stricmp(ext, ".jpg") ? PA_FORMAT_JPEG :
+ (stricmp(ext, ".jpeg") ? PA_FORMAT_JPEG :
+ (stricmp(ext, ".gif") ? PA_FORMAT_GIF :
+ (stricmp(ext, ".swf") ? PA_FORMAT_SWF : PA_FORMAT_UNKNOWN)))));
+
+
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_SUCCESS,(HANDLE) &AI, 0);
+ } else
+ ProtoBroadcastAck(MODULE,info->hContact,ACKTYPE_AVATAR,ACKRESULT_FAILED,0, 0);
+
+free_and_exit:
+ free(info->url);
+ delete info;
+}
+
+void DownloadAvatar(HANDLE hContact, char *url) {
+ av_dl_info *info = new av_dl_info;
+ info->hContact = hContact;
+ info->url = strdup(url);
+
+ mir_forkthread(sttDownloadAvatar, info);
+} \ No newline at end of file