/** triggered when someone says something */ void mwServiceConf_on_text(mwConference* conf, mwLoginInfo* user, const char* what) { CSametimeProto* proto = getProtoFromMwConference(conf); proto->debugLog(_T("mwServiceConf_on_text() start")); TCHAR* tszConfId = mir_utf8decodeT(mwConference_getName(conf)); GCDEST gcd = { proto->m_szModuleName }; gcd.ptszID = tszConfId; gcd.iType = GC_EVENT_MESSAGE; GCEVENT gce = { sizeof(gce), &gcd }; gce.dwFlags = GCEF_ADDTOLOG; TCHAR* textT = mir_utf8decodeT(what); TCHAR* tszUserName = mir_utf8decodeT(user->user_name); TCHAR* tszUserId = mir_utf8decodeT(user->login_id); gce.ptszText = textT; gce.ptszNick = tszUserName; gce.ptszUID = tszUserId; gce.time = (DWORD)time(0); CallService(MS_GC_EVENT, 0, (LPARAM)(GCEVENT *) &gce); mir_free(textT); mir_free(tszUserName); mir_free(tszUserId); mir_free(tszConfId); }
/** received an ack for a sent chunk on an outbound file transfer. this indicates that a previous call to mwFileTransfer_send has reached the target and that the target has responded. */ void mwFileTransfer_handle_ack(mwFileTransfer* ft) { // see SendThread above - not all clients send us acks CSametimeProto* proto = getProtoFromMwFileTransfer(ft); //FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("mwFileTransfer_handle_ack()")); }
void __cdecl SessionClose(mwSession* session) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionClose() server_connection=[%d]"), proto->server_connection); Netlib_CloseHandle(proto->server_connection); proto->server_connection = 0; }
void __cdecl KeepAliveThread(LPVOID param) { CSametimeProto* proto = (CSametimeProto*)param; int i = 120; proto->debugLog(_T("KeepAliveThread() start")); while (1) { if (i <= 0) { i = 120; // send keepalive every 120 * 250 = 30000[ms] if (mwSession_isStarted(proto->session) && proto->session) { mwSession_sendKeepalive(proto->session); } } i--; SleepEx(250, TRUE); EnterCriticalSection(&(proto->session_cs)); if (Miranda_Terminated() || !proto->session) { LeaveCriticalSection(&(proto->session_cs)); proto->debugLog(_T("KeepAliveThread() end")); break; } LeaveCriticalSection(&(proto->session_cs)); } return; }
void mwServiceConf_on_invited(mwConference* conf, mwLoginInfo* inviter, const char* invite) { GList *members, *mem; CSametimeProto* proto = getProtoFromMwConference(conf); proto->debugLog(_T("mwServiceConf_on_invited() start")); members = mem = mwConference_getMembers(conf); for (;mem;mem=mem->next) { if (proto->my_login_info && strcmp(proto->my_login_info->login_id, ((mwLoginInfo*)mem->data)->login_id) == 0) { proto->debugLog(_T("mwServiceConf_on_invited() already present")); char* utfs = mir_utf8encodeT(TranslateT("Invitation rejected - already present.")); mwConference_reject(conf, 0, utfs); mir_free(utfs); return; } } g_list_free(members); wchar_t ws_username[128]; MultiByteToWideChar(CP_UTF8, 0, (const char*)inviter->user_name, -1, ws_username, 128); wchar_t ws_invite[512]; MultiByteToWideChar(CP_UTF8, 0, (const char*)invite, -1, ws_invite, 128); if (MessageBoxW(0, ws_invite, ws_username, MB_OKCANCEL) == IDOK) { proto->debugLog(_T("mwServiceConf_on_invited() mwConference_accept")); mwConference_accept(conf); } else { proto->debugLog(_T("mwServiceConf_on_invited() mwConference_reject")); char* temp = mir_utf8encodeT(TranslateT("Your invitation has been rejected.")); mwConference_reject(conf, 0, temp); mir_free(temp); } }
void mwResolve_handler_details_callback(mwServiceResolve* srvc, guint32 id, guint32 code, GList* results, gpointer data) { CSametimeProto* proto = getProtoFromMwServiceResolve(srvc); MYPROTOSEARCHRESULT mpsr; memset(&mpsr, 0, sizeof(mpsr)); mpsr.cbSize = sizeof(mpsr); mpsr.nick.a = mpsr.name; if (code == mwResolveCode_SUCCESS) { GList *ri = results, *mri; for (; ri; ri = ri->next) { mri = ((mwResolveResult *)ri->data)->matches; for (; mri; mri = mri->next) { MCONTACT hContact = proto->FindContactByUserId(((mwResolveMatch*)mri->data)->id); if (hContact) { char* name = ((mwResolveMatch*)mri->data)->name; if (name && mir_strlen(name)) { db_set_utf(hContact, proto->m_szModuleName, "Name", name); db_set_utf(hContact, proto->m_szModuleName, "Nick", name); db_set_utf(hContact, "CList", "MyHandle", name); } } } } } }
void __cdecl SessionAdmin(struct mwSession* session, const char* text) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionAdmin()")); TCHAR* tt = mir_utf8decodeT(text); MessageBox(0, tt, TranslateT("Sametime administrator message"), MB_OK); mir_free(tt); }
void mwResolve_handler_callback(mwServiceResolve* srvc, guint32 id, guint32 code, GList* results, gpointer data) { CSametimeProto* proto = getProtoFromMwServiceResolve(srvc); BOOL advanced = (INT_PTR)data; MYCUSTOMSEARCHRESULTS mcsr; memset(&mcsr, 0, sizeof(mcsr)); mcsr.nSize = sizeof(MYCUSTOMSEARCHRESULTS); mcsr.psr.nick.a = mcsr.name; mcsr.nFieldCount = 4; TCHAR fields[4][512]; TCHAR *fields_addr[4]; mcsr.pszFields = fields_addr; mcsr.pszFields[0] = fields[0]; mcsr.pszFields[1] = fields[1]; mcsr.pszFields[2] = fields[2]; mcsr.pszFields[3] = fields[3]; if (advanced == TRUE) { // send column names mcsr.psr.cbSize = 0; _tcsncpy(mcsr.pszFields[0], TranslateT("ID"), 512); _tcsncpy(mcsr.pszFields[1], TranslateT("Name"), 512); _tcsncpy(mcsr.pszFields[2], TranslateT("Description"), 512); _tcsncpy(mcsr.pszFields[3], TranslateT("Group?"), 512); proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, (HANDLE)id, (LPARAM)&mcsr); } mcsr.psr.cbSize = sizeof(MYPROTOSEARCHRESULT); if (code == mwResolveCode_SUCCESS) { for (GList *ri = results; ri; ri = ri->next) { for (GList *mri = ((mwResolveResult *)ri->data)->matches; mri; mri = mri->next) { strncpy_s(mcsr.stid, ((mwResolveMatch *)mri->data)->id, _TRUNCATE); MultiByteToWideChar(CP_UTF8, 0, mcsr.stid, -1, mcsr.pszFields[0], 512); strncpy_s(mcsr.name, ((mwResolveMatch *)mri->data)->name, _TRUNCATE); MultiByteToWideChar(CP_UTF8, 0, mcsr.name, -1, mcsr.pszFields[1], 512); if (((mwResolveMatch *)mri->data)->desc) MultiByteToWideChar(CP_UTF8, 0, ((mwResolveMatch *)mri->data)->desc, -1, mcsr.pszFields[2], 512); else mcsr.pszFields[2][0] = 0; mcsr.group = (((mwResolveMatch *)mri->data)->type == mwResolveMatch_GROUP); _tcsncpy_s(mcsr.pszFields[3], 512, mcsr.group ? TranslateT("True") : TranslateT("False"), _TRUNCATE); if (advanced == TRUE) proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SEARCHRESULT, (HANDLE)id, (LPARAM)&mcsr); else proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)id, (LPARAM)&mcsr.psr); } } proto->ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)id, 0); } }
int __cdecl SessionWrite(mwSession* session, const unsigned char* buf, gsize len) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionWrite() server_connection=[%d], len=[%d]"), proto->server_connection, len); if (!proto->server_connection) return 1; if (Netlib_Send(proto->server_connection, (const char*)buf, len, 0) == SOCKET_ERROR) return 1; return 0; }
void __cdecl sttRecvAwayThread(void *param) { TFakeAckParams* tParam = (TFakeAckParams*)param; CSametimeProto* proto = tParam->proto; proto->debugLog(_T("sttRecvAwayThread() start")); Sleep(100); proto->UserRecvAwayMessage(tParam->hContact); proto->debugLog(_T("sttRecvAwayThread() end")); free(tParam); }
void __cdecl sttFakeAckMessageSuccessThread(void *param) { TFakeAckParams* tParam = (TFakeAckParams*)param; CSametimeProto* proto = tParam->proto; proto->debugLog(_T("sttFakeAckMessageSuccessThread() start")); Sleep(100); proto->ProtoBroadcastAck(tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)tParam->lParam, 0); proto->debugLog(_T("sttFakeAckMessageSuccessThread() end")); mir_free(tParam); }
void __cdecl sttFakeAckMessageFailedThread(void *param) { TFakeAckParams* tParam = (TFakeAckParams*)param; CSametimeProto* proto = tParam->proto; proto->debugLog(_T("sttFakeAckMessageFailedThread() start")); Sleep(100); proto->ProtoBroadcastAck(tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, NULL, tParam->lParam); ///TODO tParam->lParam: add error message proto->debugLog(_T("sttFakeAckMessageFailedThread() end")); mir_free(tParam); }
/** a file transfer has been fully initiated */ void mwFileTransfer_opened(mwFileTransfer* ft) { CSametimeProto* proto = getProtoFromMwFileTransfer(ft); FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("Sametime mwFileTransfer_opened start")); if (ftcd->sending) { // create a thread to send chunks - since it seems not all clients send acks for each of our chunks! mir_forkthread(SendThread, ft); } }
void __cdecl SessionAnnounce(struct mwSession* session, struct mwLoginInfo* from, gboolean may_reply, const char* text) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionAnnounce()")); TCHAR* stzFrom; TCHAR* stzText; TCHAR stzFromBuff[256]; stzFrom = mir_utf8decodeT(from->user_name); stzText = mir_utf8decodeT(text); mir_sntprintf(stzFromBuff, SIZEOF(stzFromBuff), TranslateT("Session announcement - from '%s'"), stzFrom); MessageBox(0, TranslateTS(stzText), stzFromBuff, MB_OK); mir_free(stzText); mir_free(stzFrom); }
void load_users_callback(mwServiceStorage* srvc, guint32 result, mwStorageUnit *item, gpointer data) { CSametimeProto* proto = getProtoFromMwServiceStorage(srvc); if (mwStorageUnit_getKey(item) == mwStore_AWARE_LIST) { mwGetBuffer *buff = mwGetBuffer_wrap(mwStorageUnit_asOpaque(item)); if (mwGetBuffer_remaining(buff)) { mwSametimeList* user_list = mwSametimeList_new(); mwSametimeList_get(buff, user_list); proto->ImportContactsFromList(user_list, false); mwSametimeList_free(user_list); } } }
VOID CALLBACK IdleTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { CSametimeProto* proto = (CSametimeProto*)idEvent; KillTimer(0, proto->idle_timerid); proto->idle_timerid = 0; if (proto->idle_status) { struct mwUserStatus us; us.time = (DWORD)time(0); us.status = mwStatus_IDLE; us.desc = 0; mwSession_setUserStatus(proto->session, &us); } else proto->SetSessionStatus(proto->m_iStatus); }
void __cdecl SendThread(LPVOID param) { mwFileTransfer* ft = (mwFileTransfer*)param; if (!ft) return; CSametimeProto* proto = getProtoFromMwFileTransfer(ft); FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("SendThread() start")); PROTOFILETRANSFERSTATUS pfts = {0}; pfts.cbSize = sizeof(pfts); pfts.flags = PFTS_UTF; pfts.hContact = ftcd->hContact; if (ftcd->sending == 1) pfts.flags |= PFTS_SENDING; pfts.pszFiles = NULL; pfts.totalFiles = ftcd->first->ft_count; pfts.totalBytes = ftcd->first->totalSize; while(SendFileChunk(proto, ft, ftcd) && !Miranda_Terminated()) { pfts.currentFileNumber = ftcd->ft_number; pfts.totalProgress = ftcd->sizeToHere + mwFileTransfer_getSent(ft); pfts.szWorkingDir = ftcd->save_path; pfts.szCurrentFile = (char*)mwFileTransfer_getFileName(ft); pfts.currentFileSize = mwFileTransfer_getFileSize(ft); pfts.currentFileProgress = mwFileTransfer_getSent(ft); pfts.currentFileTime = 0; //? proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftcd->hFt, (LPARAM)&pfts); SleepEx(500,TRUE); } proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftcd->hFt, 0); mwFileTransfer_removeClientData(ft); if (ftcd->save_path) free(ftcd->save_path); if (ftcd->buffer) delete[] ftcd->buffer; delete ftcd; proto->debugLog(_T("SendThread() end")); return; }
/** triggered when a conference is closed. This is typically when we've left it */ void mwServiceConf_conf_closed(mwConference* conf, guint32 reason) { CSametimeProto* proto = getProtoFromMwConference(conf); proto->debugLog(_T("mwServiceConf_conf_closed() start")); TCHAR* tszConfId = mir_utf8decodeT(mwConference_getName(conf)); GCDEST gcd = { proto->m_szModuleName }; gcd.ptszID = tszConfId; gcd.iType = GC_EVENT_CONTROL; GCEVENT gce = { sizeof(gce), &gcd }; gce.dwFlags = GCEF_ADDTOLOG; CallService(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce); CallService(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gce); mir_free(tszConfId); }
/** triggered when someone joins the conference */ void mwServiceConf_on_peer_joined(mwConference* conf, mwLoginInfo *user) { CSametimeProto* proto = getProtoFromMwConference(conf); proto->debugLog(_T("mwServiceConf_on_peer_joined() start")); MCONTACT hContact = proto->FindContactByUserId(user->user_id); if (!hContact) { mwIdBlock idb; idb.user = ((mwLoginInfo *)user)->user_id; idb.community = 0; mwSametimeList* user_list = mwSametimeList_new(); char* utfs = mir_utf8encodeT(TranslateT("None")); mwSametimeGroup* stgroup = mwSametimeGroup_new(user_list, mwSametimeGroup_NORMAL, utfs); mwSametimeUser* stuser = mwSametimeUser_new(stgroup, mwSametimeUser_NORMAL, &idb); hContact = proto->AddContact(stuser, (proto->options.add_contacts ? false : true)); mwSametimeList_free(user_list); mir_free(utfs); } ptrT tszConfId(mir_utf8decodeT(mwConference_getName(conf))); ptrT tszUserName(mir_utf8decodeT(user->user_name)); ptrT tszUserId(mir_utf8decodeT(user->login_id)); // add user GCDEST gcd = { proto->m_szModuleName }; gcd.ptszID = tszConfId; gcd.iType = GC_EVENT_JOIN; GCEVENT gce = { sizeof(gce), &gcd }; gce.dwFlags = GCEF_ADDTOLOG; gce.ptszNick = tszUserName; gce.ptszUID = tszUserId; gce.ptszStatus = _T("Normal"); gce.time = (DWORD)time(0); CallServiceSync(MS_GC_EVENT, 0, (LPARAM) &gce); mir_free(tszUserName); mir_free(tszUserId); mir_free(tszConfId); }
void __cdecl SessionStateChange(mwSession* session, mwSessionState state, gpointer info) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionStateChange() state=[%d]"), state); switch (state) { case mwSession_STARTING: break; case mwSession_HANDSHAKE: break; case mwSession_HANDSHAKE_ACK: break; case mwSession_STARTED: proto->SessionStarted(); break; case mwSession_STOPPING: if ((int)info) {// & ERR_FAILURE) { char *msg = mwError((int)info); TCHAR *msgT = mir_utf8decodeT(msg); proto->showPopup(TranslateTS(msgT), SAMETIME_POPUP_ERROR); mir_free(msgT); g_free(msg); } proto->SessionStopping(); break; case mwSession_STOPPED: break; case mwSession_LOGIN_REDIR: proto->debugLog(_T("SessionStateChange() mwSession_LOGIN_REDIR info=[%s]"), _A2T((char*)info)); //options.server_name = str((char*)info); strcpy(proto->options.server_name, (char*)info); proto->LogOut(); proto->LogIn(proto->login_status, proto->m_hNetlibUser); break; case mwSession_LOGIN_CONT: break; case mwSession_LOGIN: break; case mwSession_LOGIN_ACK: break; case mwSession_UNKNOWN: break; } }
/** triggered when someone leaves the conference */ void mwServiceConf_on_peer_parted(mwConference* conf, mwLoginInfo* user) { CSametimeProto* proto = getProtoFromMwConference(conf); proto->debugLog(_T("mwServiceConf_on_peer_parted() start")); ptrT tszConfId(mir_utf8decodeT(mwConference_getName(conf))); ptrT tszUserName(mir_utf8decodeT(user->user_name)); ptrT tszUserId(mir_utf8decodeT(user->login_id)); // remove user GCDEST gcd = { proto->m_szModuleName }; gcd.ptszID = tszConfId; gcd.iType = GC_EVENT_PART; GCEVENT gce = { sizeof(gce), &gcd }; gce.dwFlags = GCEF_ADDTOLOG; gce.ptszNick = tszUserName; gce.ptszUID = tszUserId; gce.ptszStatus = _T("Normal"); gce.time = (DWORD)time(0); CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); }
/** receive a chunk of a file from an inbound file transfer. */ void mwFileTransfer_recv(mwFileTransfer* ft, struct mwOpaque* data) { CSametimeProto* proto = getProtoFromMwFileTransfer(ft); FileTransferClientData* ftcd = (FileTransferClientData*)mwFileTransfer_getClientData(ft); proto->debugLog(_T("mwFileTransfer_recv() start")); DWORD bytes_written; if (!WriteFile(ftcd->hFile, data->data, data->len, &bytes_written, 0)) { proto->debugLog(_T("mwFileTransfer_recv() !WriteFile")); mwFileTransfer_cancel(ft); proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ftcd->hFt, 0); proto->debugLog(_T("mwFileTransfer_recv() ACKRESULT_FAILED")); } else { mwFileTransfer_ack(ft); // acknowledge chunk PROTOFILETRANSFERSTATUS pfts = { 0 }; pfts.cbSize = sizeof(pfts); pfts.flags = PFTS_UTF; pfts.hContact = ftcd->hContact; if (ftcd->sending == 1) { pfts.flags |= PFTS_SENDING; } pfts.pszFiles = NULL; pfts.totalFiles = 1; pfts.currentFileNumber = 0; pfts.totalBytes = mwFileTransfer_getFileSize(ft); pfts.totalProgress = mwFileTransfer_getSent(ft); pfts.szWorkingDir = ftcd->save_path; pfts.szCurrentFile = (char*)mwFileTransfer_getFileName(ft); pfts.currentFileSize = mwFileTransfer_getFileSize(ft); pfts.currentFileProgress = mwFileTransfer_getSent(ft); pfts.currentFileTime = 0; //? proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ftcd->hFt, (LPARAM)&pfts); proto->debugLog(_T("mwFileTransfer_recv() ACKRESULT_DATA")); if (mwFileTransfer_isDone(ft)) { proto->ProtoBroadcastAck(ftcd->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ftcd->hFt, 0); proto->debugLog(_T("mwFileTransfer_recv() ACKRESULT_SUCCESS")); } } }
void mwResolve_handler_dyngroup_callback(mwServiceResolve* srvc, guint32 id, guint32 code, GList *results, gpointer data) { CSametimeProto* proto = getProtoFromMwServiceResolve(srvc); mwSametimeGroup* stgroup = (mwSametimeGroup*)data; mwResolveResult* result; mwResolveMatch* match; g_return_if_fail(results != NULL); if (results) { result = (mwResolveResult*)results->data; if (result && result->matches) { match = (mwResolveMatch*)result->matches->data; if (match) { mwIdBlock uid; uid.user = match->id; uid.community = 0; mwSametimeUser *stuser = mwSametimeUser_new(stgroup, mwSametimeUser_NORMAL, &uid); mwSametimeUser_setShortName(stuser, match->name); MCONTACT hContact = proto->AddContact(stuser, false); const char* group_name = mwSametimeGroup_getName(stgroup); const char* group_alias = mwSametimeGroup_getAlias(stgroup); if (!group_alias) group_alias = group_name; if (hContact && group_alias && mir_strcmp(group_alias, Translate("None")) && mir_strcmp(group_alias, "MetaContacts Hidden Group")) { proto->SetContactGroup(hContact, group_alias); } } } } if (stgroup) mwSametimeList_free(mwSametimeGroup_getList(stgroup)); }
/** an incoming file transfer has been offered */ void mwFileTransfer_offered(mwFileTransfer* ft) { CSametimeProto* proto = getProtoFromMwFileTransfer(ft); proto->debugLog(_T("mwFileTransfer_offered() start")); const mwIdBlock* idb = mwFileTransfer_getUser(ft); MCONTACT hContact = proto->FindContactByUserId(idb->user); proto->debugLog(_T("Sametime mwFileTransfer_offered hContact=[%x]"), hContact); if (!hContact) { mwSametimeList* user_list = mwSametimeList_new(); mwSametimeGroup* stgroup = mwSametimeGroup_new(user_list, mwSametimeGroup_NORMAL, Translate("None")); mwSametimeUser* stuser = mwSametimeUser_new(stgroup, mwSametimeUser_NORMAL, (mwIdBlock*)idb); hContact = proto->AddContact(stuser, (proto->options.add_contacts ? false : true)); } proto->ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, (HANDLE)ft, 0); TCHAR* filenameT = mir_utf8decodeT(mwFileTransfer_getFileName(ft)); const char* message = mwFileTransfer_getMessage(ft); TCHAR descriptionT[512]; if (message) { TCHAR* messageT = mir_utf8decodeT(message); mir_sntprintf(descriptionT, _T("%s - %s"), filenameT, messageT); mir_free(messageT); } else _tcsncpy_s(descriptionT, filenameT, _TRUNCATE); PROTORECVFILET pre = {0}; pre.dwFlags = PRFF_TCHAR; pre.fileCount = 1; pre.timestamp = time(NULL); pre.descr.t = descriptionT; pre.files.t = &filenameT; pre.lParam = (LPARAM)ft; ProtoChainRecvFile(hContact, &pre); mir_free(filenameT); }
void __cdecl SessionSetPrivacyInfo(struct mwSession* session) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionSetPrivacyInfo()")); }
void mwAwareList_on_aware(mwAwareList* list, mwAwareSnapshot* aware) { CSametimeProto* proto = getProtoFromMwAwareList(list);; MCONTACT hContact = proto->FindContactByUserId(aware->id.user); char* group = 0; DBVARIANT dbv; // update self - necessary for some servers if (aware->online && !db_get_utf(0, proto->m_szModuleName, "stid", &dbv) && mir_strcmp(aware->id.user, dbv.pszVal) == 0) { int new_status = ID_STATUS_OFFLINE; switch (aware->status.status) { case mwStatus_ACTIVE: new_status = ID_STATUS_ONLINE; break; case mwStatus_AWAY: new_status = ID_STATUS_AWAY; break; case mwStatus_IDLE: new_status = ID_STATUS_IDLE; break; case mwStatus_BUSY: new_status = ID_STATUS_DND; break; case mwStatus_IN_MEETING: // link 'in meeting' Sametime status new_status = ID_STATUS_OCCUPIED; // with 'Occupied' MIR_NG status break; } if (new_status != ID_STATUS_IDLE) //SetSessionStatus(new_status); proto->UpdateSelfStatus(); db_free(&dbv); } if (hContact && !db_get_utf(hContact, "CList", "Group", &dbv)) { group = _strdup(dbv.pszVal); db_free(&dbv); } if (aware->group && (!group || mir_strcmp(aware->group, group) || !hContact)) { // dynamic group member we're not already aware of // resolve server alias to user id via resolver mwSametimeList* user_list = mwSametimeList_new(); mwSametimeGroup* stgroup = mwSametimeGroup_new(user_list, mwSametimeGroup_DYNAMIC, aware->group); char buff[256]; mir_snprintf(buff, "GA_%s", aware->group); if (!db_get_utf(0, proto->szProtoGroups, buff, &dbv)) { mwSametimeGroup_setAlias(stgroup, dbv.pszVal); db_free(&dbv); } GList* query = g_list_prepend(0, aware->id.user); mwServiceResolve_resolve(proto->service_resolve, query, mwResolveFlag_USERS, mwResolve_handler_dyngroup_callback, (gpointer)stgroup, 0); g_list_free(query); } else if (hContact) { if (aware->online) { int new_status = ID_STATUS_OFFLINE; switch (aware->status.status) { case mwStatus_ACTIVE: new_status = ID_STATUS_ONLINE; db_set_dw(hContact, proto->m_szModuleName, "IdleTS", 0); db_set_w(hContact, proto->m_szModuleName, "Status", new_status); break; case mwStatus_AWAY: new_status = ID_STATUS_AWAY; db_set_dw(hContact, proto->m_szModuleName, "IdleTS", 0); db_set_w(hContact, proto->m_szModuleName, "Status", new_status); break; case mwStatus_IDLE: if (proto->options.idle_as_away) { new_status = ID_STATUS_AWAY; db_set_w(hContact, proto->m_szModuleName, "Status", new_status); } db_set_dw(hContact, proto->m_szModuleName, "IdleTS", (DWORD)time(0)); break; case mwStatus_BUSY: new_status = ID_STATUS_DND; db_set_w(hContact, proto->m_szModuleName, "Status", new_status); db_set_dw(hContact, proto->m_szModuleName, "IdleTS", 0); break; case mwStatus_IN_MEETING: // link 'in meeting' Sametime status to 'Occipied' MIR_NG status new_status = ID_STATUS_OCCUPIED; db_set_w(hContact, proto->m_szModuleName, "Status", new_status); db_set_dw(hContact, proto->m_szModuleName, "IdleTS", 0); break; } } else db_set_w(hContact, proto->m_szModuleName, "Status", ID_STATUS_OFFLINE); if (proto->service_aware) { const char* desc = mwServiceAware_getText(proto->service_aware, &aware->id); if (desc) //db_set_utf(hContact, m_szModuleName, "StatusMsg", desc); db_set_utf(hContact, "CList", "StatusMsg", desc); else //db_set_utf(hContact, m_szModuleName, "StatusMsg", ""); //db_unset(hContact, m_szModuleName, "StatusMsg"); db_unset(hContact, "CList", "StatusMsg"); } } if (group) free(group); }
void __cdecl SessionThread(LPVOID param) { CSametimeProto* proto = (CSametimeProto*)param; HANDLE hNetlibUser = proto->m_hNetlibUser; proto->debugLog(_T("SessionThread() start")); continue_connect = true; //setup NETLIBOPENCONNECTION conn_data = { 0 }; conn_data.cbSize = sizeof(NETLIBOPENCONNECTION); conn_data.flags = NLOCF_V2; conn_data.szHost = proto->options.server_name; conn_data.wPort = proto->options.port; conn_data.timeout = 20; conn_data.waitcallback = waitcallback; proto->BroadcastNewStatus(ID_STATUS_CONNECTING); proto->server_connection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn_data); if (!proto->server_connection) { proto->BroadcastNewStatus(ID_STATUS_OFFLINE); if (continue_connect) { // real timeout - not user cancelled proto->showPopup(TranslateT("No server connection!"), SAMETIME_POPUP_ERROR); } proto->debugLog(_T("SessionThread() end, no server_connection, continue_connect=[%d]"), continue_connect); return; } mwSessionHandler handler = { 0 }; handler.clear = SessionClear; handler.io_write = SessionWrite; handler.io_close = SessionClose; handler.on_stateChange = SessionStateChange; handler.on_admin = SessionAdmin; handler.on_announce = SessionAnnounce; handler.on_setPrivacyInfo = SessionSetPrivacyInfo; handler.on_setUserStatus = SessionSetUserStatus; EnterCriticalSection(&proto->session_cs); proto->session = mwSession_new(&handler); proto->InitMeanwhileServices(); mwSession_start(proto->session); LeaveCriticalSection(&proto->session_cs); mir_forkthread(KeepAliveThread, (void*)proto); unsigned char* recv_buffer = (unsigned char*)mir_alloc(1024 * 32); int bytes; //while(session && server_connection && mwSession_getState(session) != mwSession_STOPPED) { while (proto->server_connection) {// && session) {// && !mwSession_isStopped(session)) { // break on error bytes = Netlib_Recv(proto->server_connection, (char *)recv_buffer, 1024 * 32, 0); proto->debugLog(_T("SessionThread() Netlib_Recv'ed bytes=[%d]"), bytes); if (bytes == 0) { break; } else if (bytes == SOCKET_ERROR) { // this is normal - e.g. socket closed due to log off, during blocking read above break; } else { EnterCriticalSection(&proto->session_cs); mwSession_recv(proto->session, recv_buffer, bytes); LeaveCriticalSection(&proto->session_cs); } } mir_free(recv_buffer); EnterCriticalSection(&proto->session_cs); proto->DeinitMeanwhileServices(); mwSession* old_session = proto->session; proto->session = 0; // kills keepalive thread, if awake mwSession_free(old_session); LeaveCriticalSection(&proto->session_cs); proto->BroadcastNewStatus(ID_STATUS_OFFLINE); proto->SetAllOffline(); proto->first_online = true; proto->debugLog(_T("SessionThread() end")); return; }
static INT_PTR CALLBACK DlgProcOptNet(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CSametimeProto* proto = (CSametimeProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (msg) { case WM_INITDIALOG: { TranslateDialogDefault(hwndDlg); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); proto = (CSametimeProto*)lParam; WORD client_ver = proto->GetClientVersion(); if (client_ver) { TCHAR verbuf[100]; mir_sntprintf(verbuf, _countof(verbuf), TranslateT("Client protocol version: %03d.%03d"), (client_ver & 0xFF00) >> 8, client_ver & 0xFF); SetDlgItemText(hwndDlg, IDC_ST_CLIENTVER, verbuf); } WORD server_ver = proto->GetServerVersion(); if (server_ver) { TCHAR verbuf[100]; mir_sntprintf(verbuf, _countof(verbuf), TranslateT("Server protocol version: %03d.%03d"), (server_ver & 0xFF00) >> 8, server_ver & 0xFF); SetDlgItemText(hwndDlg, IDC_ST_SERVERVER, verbuf); } TCHAR *s = mir_utf8decodeT(proto->options.server_name); SetDlgItemText(hwndDlg, IDC_ED_SNAME, s); mir_free(s); s = mir_utf8decodeT(proto->options.id); SetDlgItemText(hwndDlg, IDC_ED_NAME, s); mir_free(s); s = mir_utf8decodeT(proto->options.pword); SetDlgItemText(hwndDlg, IDC_ED_PWORD, s); mir_free(s); SetDlgItemInt(hwndDlg, IDC_ED_PORT, proto->options.port, FALSE); CheckDlgButton(hwndDlg, IDC_CHK_GETSERVERCONTACTS, proto->options.get_server_contacts ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHK_ADDCONTACTS, proto->options.add_contacts ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHK_IDLEAWAY, proto->options.idle_as_away ? BST_CHECKED : BST_UNCHECKED); SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_RESETCONTENT, 0, 0); int pos = 0; bool found = false; for (int i = 0; i < NUM_IDS; i++) { pos = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_ADDSTRING, -1, (LPARAM)client_names[i]); SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_SETITEMDATA, pos, client_ids[i]); if (client_ids[i] == proto->options.client_id) { found = true; SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_SETCURSEL, pos, 0); SetDlgItemInt(hwndDlg, IDC_ED_CLIENTID, client_ids[i], FALSE); if (i != sizeof(client_ids) / sizeof(int)-1) { HWND hw = GetDlgItem(hwndDlg, IDC_ED_CLIENTID); EnableWindow(hw, false); } } } if (!found) { SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_SETCURSEL, pos, 0); // pos is last item, i.e. custom SetDlgItemInt(hwndDlg, IDC_ED_CLIENTID, proto->options.client_id, FALSE); } SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENTVN, CB_RESETCONTENT, 0, 0); pos = 0; for (int i = 0; i < NUM_CVS; i++) { pos = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENTVN, CB_ADDSTRING, -1, (LPARAM)CV_names[i]); SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENTVN, CB_SETITEMDATA, pos, i); if (CV_major[i] == proto->options.client_versionMajor && CV_minor[i] == proto->options.client_versionMinor) { found = true; SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENTVN, CB_SETCURSEL, pos, 0); } } if (!ServiceExists(MS_POPUP_ADDPOPUPT)) { HWND hw = GetDlgItem(hwndDlg, IDC_RAD_ERRPOP); EnableWindow(hw, FALSE); } if (!ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) { HWND hw = GetDlgItem(hwndDlg, IDC_RAD_ERRBAL); EnableWindow(hw, FALSE); } switch (proto->options.err_method) { case ED_POP: CheckDlgButton(hwndDlg, IDC_RAD_ERRPOP, BST_CHECKED); break; case ED_MB: CheckDlgButton(hwndDlg, IDC_RAD_ERRMB, BST_CHECKED); break; case ED_BAL: CheckDlgButton(hwndDlg, IDC_RAD_ERRBAL, BST_CHECKED); break; } if (proto->options.encrypt_session) CheckDlgButton(hwndDlg, IDC_RAD_ENC, BST_CHECKED); else CheckDlgButton(hwndDlg, IDC_RAD_NOENC, BST_CHECKED); return FALSE; } case WM_COMMAND: if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == GetFocus()) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); if (HIWORD(wParam) == CBN_SELCHANGE) { switch (LOWORD(wParam)) { case IDC_CMB_CLIENT: { int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_GETCURSEL, 0, 0); int id = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_GETITEMDATA, sel, 0); bool custom = (id == client_ids[sizeof(client_ids) / sizeof(int)-1]); if (!custom) SetDlgItemInt(hwndDlg, IDC_ED_CLIENTID, id, FALSE); else SetDlgItemInt(hwndDlg, IDC_ED_CLIENTID, DEFAULT_ID, FALSE); HWND hw = GetDlgItem(hwndDlg, IDC_ED_CLIENTID); EnableWindow(hw, custom); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return TRUE; } case IDC_CMB_CLIENTVN: { SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return TRUE; } } } if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_BTN_UPLOADCONTACTS: { EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UPLOADCONTACTS), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_IMPORTCONTACTS), FALSE); proto->ExportContactsToServer(); SendMessage(hwndDlg, WMU_STORECOMPLETE, 0, 0); } return TRUE; case IDC_BTN_IMPORTCONTACTS: { TCHAR import_filename[MAX_PATH]; import_filename[0] = 0; OPENFILENAME ofn = { 0 }; ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = import_filename; ofn.hwndOwner = hwndDlg; ofn.Flags = CC_FULLOPEN; ofn.nMaxFile = MAX_PATH; ofn.lpstrFilter = _T("All\0*.*\0"); ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST; if (GetOpenFileName(&ofn) == TRUE) { HWND hBut = GetDlgItem(hwndDlg, IDC_BTN_UPLOADCONTACTS); EnableWindow(hBut, FALSE); hBut = GetDlgItem(hwndDlg, IDC_BTN_IMPORTCONTACTS); EnableWindow(hBut, FALSE); proto->ImportContactsFromFile(ofn.lpstrFile); SendMessage(hwndDlg, WMU_STORECOMPLETE, 0, 0); } } return TRUE; case IDC_CHK_GETSERVERCONTACTS: case IDC_CHK_ENCMESSAGES: case IDC_RAD_ERRMB: case IDC_RAD_ERRBAL: case IDC_RAD_ERRPOP: case IDC_CHK_USERCP: case IDC_CHK_ADDCONTACTS: case IDC_CHK_IDLEAWAY: case IDC_RAD_ENC: case IDC_RAD_NOENC: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return TRUE; case IDC_RAD_ANSI: case IDC_RAD_UTF8: case IDC_RAD_OEM: case IDC_RAD_UTF7: case IDC_RAD_USERCP: HWND hw = GetDlgItem(hwndDlg, IDC_CHK_USERCP); EnableWindow(hw, BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_RAD_USERCP)); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return TRUE; } } break; case WMU_STORECOMPLETE: EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UPLOADCONTACTS), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_IMPORTCONTACTS), TRUE); return TRUE; case WM_NOTIFY: if (((LPNMHDR)lParam)->code == PSN_APPLY) { TCHAR ws[2048]; GetDlgItemText(hwndDlg, IDC_ED_SNAME, ws, LSTRINGLEN); mir_strcpy(proto->options.server_name, T2Utf(ws)); GetDlgItemText(hwndDlg, IDC_ED_NAME, ws, LSTRINGLEN); mir_strcpy(proto->options.id, T2Utf(ws)); GetDlgItemText(hwndDlg, IDC_ED_PWORD, ws, LSTRINGLEN); mir_strcpy(proto->options.pword, T2Utf(ws)); BOOL translated; int port = GetDlgItemInt(hwndDlg, IDC_ED_PORT, &translated, FALSE); if (translated) proto->options.port = port; proto->options.get_server_contacts = (IsDlgButtonChecked(hwndDlg, IDC_CHK_GETSERVERCONTACTS) != FALSE); int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_GETCURSEL, 0, 0); int id = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENT, CB_GETITEMDATA, sel, 0); if (id == client_ids[sizeof(client_ids) / sizeof(int)-1]) { BOOL trans; id = GetDlgItemInt(hwndDlg, IDC_ED_CLIENTID, &trans, FALSE); if (trans) proto->options.client_id = id; } else proto->options.client_id = id; sel = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENTVN, CB_GETCURSEL, 0, 0); int CVpos = SendDlgItemMessage(hwndDlg, IDC_CMB_CLIENTVN, CB_GETITEMDATA, sel, 0); proto->options.client_versionMajor = CV_major[CVpos]; proto->options.client_versionMinor = CV_minor[CVpos]; if (IsDlgButtonChecked(hwndDlg, IDC_RAD_ERRMB)) proto->options.err_method = ED_MB; else if (IsDlgButtonChecked(hwndDlg, IDC_RAD_ERRBAL)) proto->options.err_method = ED_BAL; else if (IsDlgButtonChecked(hwndDlg, IDC_RAD_ERRPOP)) proto->options.err_method = ED_POP; proto->options.add_contacts = (IsDlgButtonChecked(hwndDlg, IDC_CHK_ADDCONTACTS) != FALSE); proto->options.encrypt_session = (IsDlgButtonChecked(hwndDlg, IDC_RAD_ENC) != FALSE); proto->options.idle_as_away = (IsDlgButtonChecked(hwndDlg, IDC_CHK_IDLEAWAY) != FALSE); proto->SaveOptions(); return TRUE; } break; case WM_DESTROY: break; } return FALSE; }
void __cdecl SessionClear(mwSession* session) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); proto->debugLog(_T("SessionClear()")); }
void __cdecl SessionSetUserStatus(struct mwSession* session) { CSametimeProto* proto = (CSametimeProto*)mwSession_getProperty(session, "PROTO_STRUCT_PTR"); int new_status; struct mwUserStatus us; mwUserStatus_clone(&us, mwSession_getUserStatus(session)); proto->debugLog(_T("SessionSetUserStatus() us.status=[%d]"), us.status); switch (us.status) { case mwStatus_ACTIVE: new_status = ID_STATUS_ONLINE; break; case mwStatus_AWAY: new_status = ID_STATUS_AWAY; if (proto->idle_status) { // ignore setting to away by idle module, after we've set ourselves idle // most standard clients represent idle and away the same way anyway, // but this allows miranda users to make use of the idle timestamp // but show our status in clist as away proto->BroadcastNewStatus(new_status); mwUserStatus_clear(&us); return; } break; case mwStatus_BUSY: new_status = ID_STATUS_DND; break; case mwStatus_IDLE: new_status = ID_STATUS_AWAY; if (!proto->first_online && !proto->options.idle_as_away) { // show our status in clist as away if idle when going online or treating idle as away mwUserStatus_clear(&us); return; } break; case mwStatus_IN_MEETING: // new 'in meeting' status new_status = ID_STATUS_OCCUPIED; break; default: TCHAR buff[512]; mir_sntprintf(buff, SIZEOF(buff), TranslateT("Unknown user status: %d"), us.status); proto->showPopup(buff, SAMETIME_POPUP_ERROR); proto->debugLog(buff); mwUserStatus_clear(&us); // just go online...to prevent us getting stuck 'connecting' new_status = ID_STATUS_ONLINE; break; } proto->m_iDesiredStatus = new_status; if (proto->first_online) { proto->first_online = false; //proto->showPopup(TranslateT("Setting login status"), SAMETIME_POPUP_INFO); proto->debugLog(_T("Setting login status")); proto->SetSessionStatus(proto->login_status); } else proto->BroadcastNewStatus(new_status); mwUserStatus_clear(&us); }