From 6ad2fdede0ae25dc0d56b5e45f6b9aa876e93b68 Mon Sep 17 00:00:00 2001 From: sje Date: Tue, 3 Jul 2007 06:26:19 +0000 Subject: don't strip links in tags get avatars! woohoo :) git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@248 4f64403b-2f21-0410-a795-97e2b3489a10 --- MySpace/server_con.cpp | 270 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 265 insertions(+), 5 deletions(-) (limited to 'MySpace/server_con.cpp') 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 #include +#include #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;iheadersCount;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 -- cgit v1.2.3