diff options
author | George Hazan <george.hazan@gmail.com> | 2024-08-07 17:19:37 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-08-07 17:19:37 +0300 |
commit | 5732a19c7dd15ee2a70fb30b3b27db9514208d2f (patch) | |
tree | c414a6c6582bfdf263b36edf31f6bdb249f9788b | |
parent | af775d509bf12dd75cdc5088a04bd39cae06ef30 (diff) |
fixes #4542 (SkypeWeb: Load Server History втягивает только некоторое количество свежих сообщений, а не всю историю)
-rw-r--r-- | protocols/SkypeWeb/src/requests/files.h | 34 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/requests/history.h | 23 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/requests/messages.h | 4 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_chatrooms.cpp | 22 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_files.cpp | 32 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_history_sync.cpp | 62 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_messages.cpp | 61 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_proto.h | 8 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_utils.cpp | 17 | ||||
-rw-r--r-- | protocols/SkypeWeb/src/skype_utils.h | 16 |
10 files changed, 142 insertions, 137 deletions
diff --git a/protocols/SkypeWeb/src/requests/files.h b/protocols/SkypeWeb/src/requests/files.h index 0517385bf3..7c04baabfb 100644 --- a/protocols/SkypeWeb/src/requests/files.h +++ b/protocols/SkypeWeb/src/requests/files.h @@ -16,12 +16,15 @@ struct ASMObjectCreateRequest : public AsyncHttpRequest T2Utf uszFileName(fup->tszFileName); const char *szFileName = strrchr(uszFileName.get() + 1, '\\'); - JSONNode node, jPermissions, jPermission(JSON_ARRAY); - jPermissions.set_name("permissions"); - jPermission.set_name(szContact.c_str()); - jPermission << CHAR_PARAM("", "read"); - jPermissions << jPermission; - node << CHAR_PARAM("type", "sharing/file") << CHAR_PARAM("filename", szFileName) << jPermissions; + JSONNode node; + if (fup->isPicture) + node << CHAR_PARAM("type", "pish/image"); + else + node << CHAR_PARAM("type", "sharing/file"); + + JSONNode jPermission(JSON_ARRAY); jPermission.set_name(szContact.c_str()); jPermission << CHAR_PARAM("", "read"); + JSONNode jPermissions; jPermissions.set_name("permissions"); jPermissions << jPermission; + node << CHAR_PARAM("filename", szFileName) << jPermissions; m_szParam = node.write().c_str(); } }; @@ -31,11 +34,12 @@ struct ASMObjectUploadRequest : public AsyncHttpRequest ASMObjectUploadRequest(CSkypeProto *ppro, const char *szObject, const uint8_t *data, int size, CFileUploadParam *fup) : AsyncHttpRequest(REQUEST_PUT, HOST_OTHER, 0, &CSkypeProto::OnASMObjectUploaded) { - m_szUrl.AppendFormat("https://api.asm.skype.com/v1/objects/%s/content/original", szObject); + m_szUrl.AppendFormat("https://api.asm.skype.com/v1/objects/%s/content/%s", + szObject, fup->isPicture ? "imgpsh" : "original"); pUserInfo = fup; AddHeader("Authorization", CMStringA(FORMAT, "skype_token %s", ppro->m_szApiToken.get())); - AddHeader("Content-Type", "application/octet-stream"); + AddHeader("Content-Type", fup->isPicture ? "application" : "application/octet-stream"); m_szParam.Truncate(size); memcpy(m_szParam.GetBuffer(), data, size); @@ -44,16 +48,20 @@ struct ASMObjectUploadRequest : public AsyncHttpRequest struct SendFileRequest : public AsyncHttpRequest { - SendFileRequest(const char *username, time_t timestamp, const char *message, const char *messageType, const char *asmRef) : + SendFileRequest(CFileUploadParam *fup, const char *username, const char *message) : AsyncHttpRequest(REQUEST_POST, HOST_DEFAULT, 0, &CSkypeProto::OnMessageSent) { m_szUrl.AppendFormat("/users/ME/conversations/%s/messages", mir_urlEncode(username).c_str()); - JSONNode node, ref(JSON_ARRAY); - ref.set_name("amsreferences"); ref.push_back(JSONNode("", asmRef)); + JSONNode ref(JSON_ARRAY); ref.set_name("amsreferences"); ref << CHAR_PARAM("", fup->uid); + + JSONNode node; + if (fup->isPicture) + node << CHAR_PARAM("messagetype", "RichText/UriObject"); + else + node << CHAR_PARAM("messagetype", "RichText/Media_GenericFile"); - node << INT64_PARAM("clientmessageid", timestamp) << CHAR_PARAM("messagetype", messageType) - << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", message) << ref; + node << INT64_PARAM("clientmessageid", time(0)) << CHAR_PARAM("contenttype", "text") << CHAR_PARAM("content", message) << ref; m_szParam = node.write().c_str(); } }; diff --git a/protocols/SkypeWeb/src/requests/history.h b/protocols/SkypeWeb/src/requests/history.h index ecd3fbcb65..4e63278f8c 100644 --- a/protocols/SkypeWeb/src/requests/history.h +++ b/protocols/SkypeWeb/src/requests/history.h @@ -21,35 +21,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. struct SyncHistoryFirstRequest : public AsyncHttpRequest
{
SyncHistoryFirstRequest(int pageSize) :
- AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, "/users/ME/conversations", &CSkypeProto::OnSyncHistory)
+ AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, "/users/ME/conversations", &CSkypeProto::OnSyncConversations)
{
this << INT_PARAM("startTime", 0) << INT_PARAM("pageSize", pageSize)
<< CHAR_PARAM("view", "msnp24Equivalent") << CHAR_PARAM("targetType", "Passport|Skype|Lync");
}
-
- SyncHistoryFirstRequest(const char *url) :
- AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, url, &CSkypeProto::OnSyncHistory)
- {
- }
};
struct GetHistoryRequest : public AsyncHttpRequest
{
- GetHistoryRequest(const char *who, int pageSize, uint32_t timestamp, bool bOperative) :
- AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, "/users/ME/conversations/" + mir_urlEncode(who) + "/messages", &CSkypeProto::OnGetServerHistory)
+ CMStringA m_who;
+
+ GetHistoryRequest(MCONTACT _1, const char *who, int pageSize, int64_t timestamp, bool bOperative) :
+ AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, "/users/ME/conversations/" + mir_urlEncode(who) + "/messages", &CSkypeProto::OnGetServerHistory),
+ m_who(who)
{
+ hContact = _1;
if (bOperative)
pUserInfo = this;
- this << INT_PARAM("startTime", timestamp) << INT_PARAM("pageSize", pageSize)
+ this << INT64_PARAM("startTime", timestamp) << INT_PARAM("pageSize", pageSize)
<< CHAR_PARAM("view", "msnp24Equivalent") << CHAR_PARAM("targetType", "Passport|Skype|Lync|Thread");
}
-
- GetHistoryRequest(const char *url, void *pInfo) :
- AsyncHttpRequest(REQUEST_GET, HOST_DEFAULT, url, &CSkypeProto::OnGetServerHistory)
- {
- pUserInfo = pInfo;
- }
};
struct EmptyHistoryRequest : public AsyncHttpRequest
diff --git a/protocols/SkypeWeb/src/requests/messages.h b/protocols/SkypeWeb/src/requests/messages.h index e51718e508..a6d9cf4916 100644 --- a/protocols/SkypeWeb/src/requests/messages.h +++ b/protocols/SkypeWeb/src/requests/messages.h @@ -71,13 +71,13 @@ struct SendTypingRequest : public AsyncHttpRequest struct MarkMessageReadRequest : public AsyncHttpRequest
{
- MarkMessageReadRequest(const char *username, LONGLONG /*msgId*/, LONGLONG msgTimestamp) :
+ MarkMessageReadRequest(const char *username, int64_t msgTimestamp) :
AsyncHttpRequest(REQUEST_PUT, HOST_DEFAULT)
{
m_szUrl.AppendFormat("/users/ME/conversations/%s/properties?name=consumptionhorizon", mir_urlEncode(username).c_str());
JSONNode node(JSON_NODE);
- node << CHAR_PARAM("consumptionhorizon", CMStringA(::FORMAT, "%lld000;%lld000;%lld000", msgTimestamp, time(NULL), msgTimestamp));
+ node << CHAR_PARAM("consumptionhorizon", CMStringA(::FORMAT, "%lld;%lld;%lld", msgTimestamp, msgTimestamp, msgTimestamp));
m_szParam = node.write().c_str();
}
};
diff --git a/protocols/SkypeWeb/src/skype_chatrooms.cpp b/protocols/SkypeWeb/src/skype_chatrooms.cpp index de29ccfe0e..118a7ec3e8 100644 --- a/protocols/SkypeWeb/src/skype_chatrooms.cpp +++ b/protocols/SkypeWeb/src/skype_chatrooms.cpp @@ -40,15 +40,17 @@ SESSION_INFO* CSkypeProto::StartChatRoom(const wchar_t *tid, const wchar_t *tnam if (!si)
return nullptr;
- // Create a user statuses
- Chat_AddGroup(si, TranslateT("Admin"));
- Chat_AddGroup(si, TranslateT("User"));
+ if (si->arUsers.getCount() == 0) {
+ // Create a user statuses
+ Chat_AddGroup(si, TranslateT("Admin"));
+ Chat_AddGroup(si, TranslateT("User"));
+
+ PushRequest(new GetChatInfoRequest(tid));
+ }
// Finish initialization
Chat_Control(si, (getBool("HideChats", 1) ? WINDOW_HIDDEN : SESSION_INITDONE));
Chat_Control(si, SESSION_ONLINE);
-
- PushRequest(new GetChatInfoRequest(tid));
return si;
}
@@ -59,14 +61,10 @@ void CSkypeProto::OnLoadChats(MHttpResponse *response, AsyncHttpRequest*) return;
auto &root = reply.data();
- const JSONNode &metadata = root["_metadata"];
+ // const JSONNode &metadata = root["_metadata"];
const JSONNode &conversations = root["conversations"].as_array();
- int totalCount = metadata["totalCount"].as_int();
- std::string syncState = metadata["syncState"].as_string();
-
- if (totalCount >= 99 || conversations.size() >= 99)
- ReadHistoryRest(syncState.c_str());
+ // int totalCount = metadata["totalCount"].as_int();
for (auto &it : conversations) {
auto &props = it["threadProperties"];
@@ -373,7 +371,7 @@ void CSkypeProto::OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest*) AddChatContact(si, username, role, true);
}
- PushRequest(new GetHistoryRequest(T2Utf(si->ptszID), 100, 0, true));
+ PushRequest(new GetHistoryRequest(si->hContact, T2Utf(si->ptszID), 100, 0, true));
}
wchar_t* CSkypeProto::GetChatContactNick(MCONTACT hContact, const wchar_t *id, const wchar_t *name)
diff --git a/protocols/SkypeWeb/src/skype_files.cpp b/protocols/SkypeWeb/src/skype_files.cpp index a9d6512498..2d6bd2c163 100644 --- a/protocols/SkypeWeb/src/skype_files.cpp +++ b/protocols/SkypeWeb/src/skype_files.cpp @@ -28,10 +28,13 @@ void CSkypeProto::ReceiveFileThread(void *param) CMStringA szCookie, szUrl;
szCookie.AppendFormat("skypetoken_asm=%s", m_szApiToken.get());
{
+ auto &json = dbei.getJson();
+ auto skft = json["skft"].as_string();
+
MHttpRequest nlhr(REQUEST_GET);
nlhr.flags = NLHRF_HTTP11 | NLHRF_NOUSERAGENT;
nlhr.m_szUrl = blob.getUrl();
- nlhr.m_szUrl += "/views/original/status";
+ nlhr.m_szUrl.AppendFormat("/views/%s/status", skft == "Picture.1" ? "imgpsh_mobile_save_anim" : "original");
nlhr.AddHeader("Accept", "*/*");
nlhr.AddHeader("Accept-Encoding", "gzip, deflate");
nlhr.AddHeader("Cookie", szCookie);
@@ -105,6 +108,13 @@ void CSkypeProto::SendFileThread(void *p) return;
}
+ if (auto *pBitmap = FreeImage_LoadU(FreeImage_GetFIFFromFilenameU(fup->tszFileName), fup->tszFileName)) {
+ fup->isPicture = true;
+ fup->width = FreeImage_GetWidth(pBitmap);
+ fup->height = FreeImage_GetHeight(pBitmap);
+ FreeImage_Unload(pBitmap);
+ }
+
ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)fup);
PushRequest(new ASMObjectCreateRequest(this, fup));
}
@@ -174,22 +184,20 @@ void CSkypeProto::OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest // is that a picture?
CMStringA href;
- bool bIsPictture = false;
- if (auto *pBitmap = FreeImage_LoadU(FreeImage_GetFIFFromFilenameU(fup->tszFileName), fup->tszFileName)) {
- bIsPictture = true;
- pRoot->SetAttribute("type", "File.1" /*"Picture.1"*/);
+ if (fup->isPicture) {
+ pRoot->SetAttribute("type", "Picture.1");
pRoot->SetAttribute("url_thumbnail", CMStringA(FORMAT, "https://api.asm.skype.com/v1/objects/%s/views/imgt1_anim", fup->uid.get()));
- pRoot->SetAttribute("width", FreeImage_GetWidth(pBitmap));
- pRoot->SetAttribute("height", FreeImage_GetHeight(pBitmap));
- pRoot->SetText("To view this file, go to:");
- FreeImage_Unload(pBitmap);
+ pRoot->SetAttribute("width", fup->width);
+ pRoot->SetAttribute("height", fup->height);
+ pRoot->SetText("To view this shared photo, go to:");
href.Format("https://login.skype.com/login/sso?go=xmmfallback?pic=%s", fup->uid.get());
}
else {
pRoot->SetAttribute("type", "File.1");
pRoot->SetAttribute("url_thumbnail", CMStringA(FORMAT, "https://api.asm.skype.com/v1/objects/%s/views/original", fup->uid.get()));
- pRoot->SetText("To view this shared photo, go to:");
+ pRoot->SetText("To view this file, go to:");
+
href.Format("https://login.skype.com/login/sso?go=webclient.xmm&docid=%s", fup->uid.get());
}
@@ -200,7 +208,7 @@ void CSkypeProto::OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest auto *xmlOrigName = doc.NewElement("OriginalName"); xmlOrigName->SetAttribute("v", tszFile); pRoot->InsertEndChild(xmlOrigName);
auto *xmlSize = doc.NewElement("FileSize"); xmlSize->SetAttribute("v", (int)fup->size); pRoot->InsertEndChild(xmlSize);
- if (bIsPictture) {
+ if (fup->isPicture) {
auto xmlMeta = doc.NewElement("meta");
xmlMeta->SetAttribute("type", "photo"); xmlMeta->SetAttribute("originalName", tszFile);
pRoot->InsertEndChild(xmlMeta);
@@ -214,7 +222,7 @@ void CSkypeProto::OnASMObjectUploaded(MHttpResponse *response, AsyncHttpRequest Utils_GetRandom(¶m->hMessage, sizeof(param->hMessage));
param->hMessage &= ~0x80000000;
- auto *pReq = new SendFileRequest(getId(fup->hContact), time(NULL), printer.CStr(), "RichText/Media_GenericFile", fup->uid);
+ auto *pReq = new SendFileRequest(fup, getId(fup->hContact), printer.CStr());
pReq->pUserInfo = param;
PushRequest(pReq);
diff --git a/protocols/SkypeWeb/src/skype_history_sync.cpp b/protocols/SkypeWeb/src/skype_history_sync.cpp index 294800d304..a1e86c777b 100644 --- a/protocols/SkypeWeb/src/skype_history_sync.cpp +++ b/protocols/SkypeWeb/src/skype_history_sync.cpp @@ -25,6 +25,7 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * if (reply.error())
return;
+ auto *pOrig = (GetHistoryRequest *)pRequest;
auto &root = reply.data();
const JSONNode &metadata = root["_metadata"];
@@ -33,7 +34,9 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * bool markAllAsUnread = getBool("MarkMesUnread", true);
bool bUseLocalTime = !bUseServerTime && pRequest->pUserInfo != 0;
- uint32_t lastMsgTime = 0;
+ bool bSetLastTime = false;
+
+ int64_t lastMsgTime = 0; // max timestamp on this page
time_t iLocalTime = time(0);
auto &conv = root["messages"];
@@ -47,24 +50,19 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * MCONTACT hContact = FindContact(szChatId);
- time_t timestamp = IsoToUnixTime(message["composetime"].as_string());
- if (timestamp > getDword(hContact, "LastMsgTime", 0))
- setDword(hContact, "LastMsgTime", timestamp);
-
DB::EventInfo dbei(db_event_getById(m_szModuleName, szMessageId));
dbei.hContact = hContact;
dbei.szModule = m_szModuleName;
- dbei.timestamp = timestamp;
+ dbei.timestamp = (bUseLocalTime) ? iLocalTime : IsoToUnixTime(message["composetime"].as_string());
dbei.szId = szMessageId;
if (iUserType == 19)
dbei.szUserId = szFrom;
- uint32_t id = message["id"].as_int();
- if (id > lastMsgTime)
+ int64_t id = _atoi64(message["id"].as_string().c_str());
+ if (id > lastMsgTime) {
+ bSetLastTime = true;
lastMsgTime = id;
-
- if (bUseLocalTime)
- timestamp = iLocalTime;
+ }
dbei.flags = DBEF_UTF;
if (!markAllAsUnread)
@@ -80,37 +78,20 @@ void CSkypeProto::OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest * }
}
- if (totalCount >= 99 || conv.size() >= 99) {
- CMStringA szUrl(pRequest->m_szUrl);
- int i1 = szUrl.Find("startTime=");
- int i2 = szUrl.Find("&", i1);
- if (i1 != -1 && i2 != -1) {
- i1 += 10;
- szUrl.Delete(i1, i2 - i1);
-
- char buf[100];
- itoa(lastMsgTime, buf, sizeof(buf));
- szUrl.Insert(i1, buf);
-
- PushRequest(new GetHistoryRequest(szUrl, pRequest->pUserInfo));
- }
- }
-}
+ if (bSetLastTime && lastMsgTime > getLastTime(pOrig->hContact))
+ setLastTime(pOrig->hContact, lastMsgTime);
-void CSkypeProto::ReadHistoryRest(const char *szUrl)
-{
- auto *p = strstr(szUrl, g_plugin.szDefaultServer);
- if (p)
- PushRequest(new SyncHistoryFirstRequest(p+ g_plugin.szDefaultServer.GetLength()+3));
+ if (totalCount >= 99 || conv.size() >= 99)
+ PushRequest(new GetHistoryRequest(pOrig->hContact, pOrig->m_who, 100, lastMsgTime, pRequest->pUserInfo != 0));
}
INT_PTR CSkypeProto::SvcLoadHistory(WPARAM hContact, LPARAM)
{
- PushRequest(new GetHistoryRequest(getId(hContact), 100, 0, false));
+ PushRequest(new GetHistoryRequest(hContact, getId(hContact), 100, 0, false));
return 0;
}
-void CSkypeProto::OnSyncHistory(MHttpResponse *response, AsyncHttpRequest*)
+void CSkypeProto::OnSyncConversations(MHttpResponse *response, AsyncHttpRequest*)
{
JsonReply reply(response);
if (reply.error())
@@ -120,12 +101,9 @@ void CSkypeProto::OnSyncHistory(MHttpResponse *response, AsyncHttpRequest*) const JSONNode &metadata = root["_metadata"];
const JSONNode &conversations = root["conversations"].as_array();
- int totalCount = metadata["totalCount"].as_int();
+ // int totalCount = metadata["totalCount"].as_int();
std::string syncState = metadata["syncState"].as_string();
- if (totalCount >= 99 || conversations.size() >= 99)
- ReadHistoryRest(syncState.c_str());
-
for (auto &conversation : conversations) {
const JSONNode &lastMessage = conversation["lastMessage"];
if (!lastMessage)
@@ -135,13 +113,13 @@ void CSkypeProto::OnSyncHistory(MHttpResponse *response, AsyncHttpRequest*) std::string strConversationLink = lastMessage["conversationLink"].as_string();
CMStringA szSkypename = UrlToSkypeId(strConversationLink.c_str(), &iUserType);
if (iUserType == 8 || iUserType == 2) {
- time_t composeTime(IsoToUnixTime(lastMessage["composetime"].as_string()));
+ int64_t id = _atoi64(lastMessage["id"].as_string().c_str());
MCONTACT hContact = FindContact(szSkypename);
if (hContact != NULL) {
- uint32_t lastMsgTime = getDword(hContact, "LastMsgTime", 0);
- if (lastMsgTime && lastMsgTime < composeTime)
- PushRequest(new GetHistoryRequest(szSkypename, 100, lastMsgTime, true));
+ auto lastMsgTime = getLastTime(hContact);
+ if (lastMsgTime && lastMsgTime < id)
+ PushRequest(new GetHistoryRequest(hContact, szSkypename, 100, lastMsgTime, true));
}
}
}
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp index 8ceb243d0a..22ad6918b9 100644 --- a/protocols/SkypeWeb/src/skype_messages.cpp +++ b/protocols/SkypeWeb/src/skype_messages.cpp @@ -93,7 +93,7 @@ bool CSkypeProto::ParseMessage(const JSONNode &node, DB::EventInfo &dbei) CMStringW wszContent = node["content"].as_mstring();
std::string strMessageType = node["messagetype"].as_string();
- if (strMessageType == "RichText/Media_GenericFile") {
+ if (strMessageType == "RichText/Media_GenericFile" || strMessageType == "RichText/UriObject") {
ProcessFileRecv(dbei.hContact, node["content"].as_string().c_str(), dbei);
return false;
}
@@ -152,9 +152,11 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) MCONTACT hContact = AddContact(szConversationName, nullptr, true);
- time_t timestamp = time(0); // fuck the server time, we need to place events in the order of our local time
- if (m_bHistorySynced)
- setDword(hContact, "LastMsgTime", timestamp);
+ if (m_bHistorySynced) {
+ int64_t lastMsgId = _atoi64(node["id"].as_string().c_str());
+ if (lastMsgId > getLastTime(hContact))
+ setLastTime(hContact, lastMsgId);
+ }
if (iUserType == 19)
if (OnChatEvent(node))
@@ -172,7 +174,7 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) DB::EventInfo dbei(db_event_getById(m_szModuleName, szMessageId));
dbei.hContact = hContact;
- dbei.timestamp = timestamp;
+ dbei.timestamp = time(0);
dbei.szId = szMessageId;
dbei.flags = DBEF_UTF;
if (IsMe(szFromSkypename))
@@ -190,20 +192,11 @@ void CSkypeProto::ProcessNewMessage(const JSONNode &node) void CSkypeProto::OnMarkRead(MCONTACT hContact, MEVENT hDbEvent)
{
- if (IsOnline() && !isChatRoom(hContact))
- MarkMessagesRead(hContact, hDbEvent);
-}
-
-void CSkypeProto::MarkMessagesRead(MCONTACT hContact, MEVENT hDbEvent)
-{
- debugLogA(__FUNCTION__);
-
- DBEVENTINFO dbei = {};
- db_event_get(hDbEvent, &dbei);
- time_t timestamp = dbei.timestamp;
-
- if (getDword(hContact, "LastMsgTime") > (timestamp - 300))
- PushRequest(new MarkMessageReadRequest(getId(hContact), timestamp, timestamp));
+ if (IsOnline()) {
+ DB::EventInfo dbei(hDbEvent, false);
+ if (dbei && dbei.szId)
+ PushRequest(new MarkMessageReadRequest(getId(hContact), _atoi64(dbei.szId)));
+ }
}
void CSkypeProto::OnReceiveOfflineFile(DB::FILE_BLOB &blob)
@@ -247,22 +240,24 @@ void CSkypeProto::ProcessFileRecv(MCONTACT hContact, const char *szContent, DB:: }
// ordinary file
- if (!mir_strcmp(pszFileType, "File.1")) {
- }
- else {
- debugLogA("Invalid or unsupported file type <%s> ignored", pszFileType);
- return;
- }
+ if (!mir_strcmp(pszFileType, "File.1") || !mir_strcmp(pszFileType, "Picture.1")) {
+ MEVENT hEvent;
+ dbei.flags |= DBEF_TEMPORARY | DBEF_JSON;
+ if (dbei) {
+ DB::FILE_BLOB blob(dbei);
+ OnReceiveOfflineFile(blob);
+ blob.write(dbei);
+ db_event_edit(dbei.getEvent(), &dbei, true);
+ delete ft;
+ hEvent = dbei.getEvent();
+ }
+ else hEvent = ProtoChainRecvFile(hContact, DB::FILE_BLOB(ft, ft->fileName), dbei);
- dbei.flags |= DBEF_TEMPORARY;
- if (dbei) {
- DB::FILE_BLOB blob(dbei);
- OnReceiveOfflineFile(blob);
- blob.write(dbei);
- db_event_edit(dbei.getEvent(), &dbei, true);
- delete ft;
+ DBVARIANT dbv = { DBVT_UTF8 };
+ dbv.pszVal = (char*)pszFileType;
+ db_event_setJson(hEvent, "skft", &dbv);
}
- else ProtoChainRecvFile(hContact, DB::FILE_BLOB(ft, ft->fileName), dbei);
+ else debugLogA("Invalid or unsupported file type <%s> ignored", pszFileType);
}
void CSkypeProto::ProcessContactRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei)
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index 1a4cccda18..c3fd62b343 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -159,7 +159,7 @@ public: void OnMessageSent(MHttpResponse *response, AsyncHttpRequest *pRequest);
void OnGetServerHistory(MHttpResponse *response, AsyncHttpRequest *pRequest);
- void OnSyncHistory(MHttpResponse *response, AsyncHttpRequest *pRequest);
+ void OnSyncConversations(MHttpResponse *response, AsyncHttpRequest *pRequest);
void OnLoadChats(MHttpResponse *response, AsyncHttpRequest *pRequest);
void OnGetChatInfo(MHttpResponse *response, AsyncHttpRequest *pRequest);
@@ -261,8 +261,6 @@ private: int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
- void MarkMessagesRead(MCONTACT hContact, MEVENT hDbEvent);
-
void ProcessContactRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei);
void ProcessFileRecv(MCONTACT hContact, const char *szContent, DB::EventInfo &dbei);
@@ -298,7 +296,6 @@ private: void ProcessConversationUpdate(const JSONNode &node);
void RefreshStatuses(void);
- void ReadHistoryRest(const char *url);
// utils
template <typename T>
@@ -315,6 +312,9 @@ private: bool IsMe(const wchar_t *str);
bool IsMe(const char *str);
+ int64_t getLastTime(MCONTACT);
+ void setLastTime(MCONTACT, int64_t);
+
static time_t IsoToUnixTime(const std::string &stamp);
static int SkypeToMirandaStatus(const char *status);
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp index e3af5b6c74..78487e0850 100644 --- a/protocols/SkypeWeb/src/skype_utils.cpp +++ b/protocols/SkypeWeb/src/skype_utils.cpp @@ -79,6 +79,8 @@ time_t CSkypeProto::IsoToUnixTime(const std::string &stamp) return (t >= 0) ? t : 0;
}
+//////////////////////////////////////////////////////////////////////////////////////////
+
struct HtmlEntity
{
const char *entity;
@@ -477,6 +479,21 @@ bool CSkypeProto::IsMe(const char *str) //////////////////////////////////////////////////////////////////////////////////////////
+int64_t CSkypeProto::getLastTime(MCONTACT hContact)
+{
+ ptrA szLastTime(getStringA(hContact, "LastMsgTime"));
+ return (szLastTime) ? _atoi64(szLastTime) : 0;
+}
+
+void CSkypeProto::setLastTime(MCONTACT hContact, int64_t iValue)
+{
+ char buf[100];
+ _i64toa(iValue, buf, 10);
+ setString(hContact, "LastMsgTime", buf);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
bool CSkypeProto::IsFileExists(std::wstring path)
{
return _waccess(path.c_str(), 0) == 0;
diff --git a/protocols/SkypeWeb/src/skype_utils.h b/protocols/SkypeWeb/src/skype_utils.h index 5acdb1b856..2835ae45da 100644 --- a/protocols/SkypeWeb/src/skype_utils.h +++ b/protocols/SkypeWeb/src/skype_utils.h @@ -42,16 +42,24 @@ public: __inline operator HANDLE() { return _hEvent; }
};
-struct CFileUploadParam : public MZeroedObject {
+struct CFileUploadParam : public MZeroedObject
+{
ptrW tszFileName;
ptrW tszDesc;
ptrA atr;
ptrA fname;
ptrA uid;
- size_t size;
+ long size;
+ int width, height;
MCONTACT hContact;
-
- __forceinline CFileUploadParam(MCONTACT _hContact, const wchar_t* _desc, wchar_t** _files) : hContact(_hContact), tszDesc(mir_wstrdup(_desc)), tszFileName(mir_wstrdup(_files[0])) {};
+ bool isPicture;
+
+ __forceinline CFileUploadParam(MCONTACT _hContact, const wchar_t* _desc, wchar_t** _files) :
+ hContact(_hContact),
+ tszDesc(mir_wstrdup(_desc)),
+ tszFileName(mir_wstrdup(_files[0]))
+ {};
+
__forceinline bool IsAccess() { return ::_waccess(tszFileName, 0) == 0; }
};
|