From f974117ce015abf0bc7b42228cacac7aece91b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 14 Apr 2020 12:00:20 +0200 Subject: [PATCH] download to .%pid%.tmp, rename to .map when done The commit message is misleading. DDNet already had the pid.tmp behavior. This just uses more the teeworlds style of doing it. (cherry picked from commit https://github.com/teeworlds/teeworlds/commit/0da0cb80449d0aa01fe21737b5330beddfdc9975) --- src/engine/client/client.cpp | 147 +++++++++++++++++------------------ src/engine/client/client.h | 3 +- 2 files changed, 72 insertions(+), 78 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 4184703be..e5bb59d06 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -313,9 +313,10 @@ CClient::CClient() : // map download m_aMapdownloadFilename[0] = 0; + m_aMapdownloadFilenameTemp[0] = 0; m_aMapdownloadName[0] = 0; m_pMapdownloadTask = NULL; - m_MapdownloadFile = 0; + m_MapdownloadFileTemp = 0; m_MapdownloadChunk = 0; m_MapdownloadSha256Present = false; m_MapdownloadSha256 = SHA256_ZEROED; @@ -456,12 +457,12 @@ void CClient::SendReady() void CClient::SendMapRequest() { - if(m_MapdownloadFile) + if(m_MapdownloadFileTemp) { - io_close(m_MapdownloadFile); - Storage()->RemoveFile(m_aMapdownloadFilename, IStorage::TYPE_SAVE); + io_close(m_MapdownloadFileTemp); + Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE); } - m_MapdownloadFile = Storage()->OpenFile(m_aMapdownloadFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE); + m_MapdownloadFileTemp = Storage()->OpenFile(m_aMapdownloadFilenameTemp, IOFLAG_WRITE, IStorage::TYPE_SAVE); CMsgPacker Msg(NETMSG_REQUEST_MAP_DATA, true); Msg.AddInt(m_MapdownloadChunk); SendMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); @@ -803,12 +804,12 @@ void CClient::DisconnectWithReason(const char *pReason) m_MapdownloadChunk = 0; if(m_pMapdownloadTask) m_pMapdownloadTask->Abort(); - if(m_MapdownloadFile) + if(m_MapdownloadFileTemp) { - io_close(m_MapdownloadFile); - Storage()->RemoveFile(m_aMapdownloadFilename, IStorage::TYPE_SAVE); + io_close(m_MapdownloadFileTemp); + Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE); } - m_MapdownloadFile = 0; + m_MapdownloadFileTemp = 0; m_MapdownloadSha256Present = false; m_MapdownloadSha256 = SHA256_ZEROED; m_MapdownloadCrc = 0; @@ -1217,24 +1218,43 @@ const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DI return 0; } +static void FormatMapDownloadFilename(const char *pName, const SHA256_DIGEST *pSha256, int Crc, bool Temp, char *pBuffer, int BufferSize) +{ + char aSuffix[32]; + if(Temp) + { + str_format(aSuffix, sizeof(aSuffix), ".%d.tmp", pid()); + } + else + { + str_copy(aSuffix, ".map", sizeof(aSuffix)); + } + + if(pSha256) + { + char aSha256[SHA256_MAXSTRSIZE]; + sha256_str(*pSha256, aSha256, sizeof(aSha256)); + str_format(pBuffer, BufferSize, "downloadedmaps/%s_%s%s", pName, aSha256, aSuffix); + } + else + { + str_format(pBuffer, BufferSize, "downloadedmaps/%s_%08x%s", pName, Crc, aSuffix); + } +} + const char *CClient::LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedSha256, int WantedCrc) { const char *pError = 0; char aBuf[512]; - char aWanted[256]; - char aWantedSha256[SHA256_MAXSTRSIZE]; - + char aWanted[SHA256_MAXSTRSIZE + 16]; + aWanted[0] = 0; if(pWantedSha256) { + char aWantedSha256[SHA256_MAXSTRSIZE]; sha256_str(*pWantedSha256, aWantedSha256, sizeof(aWantedSha256)); - str_format(aWanted, sizeof(aWanted), "sha256=%s", aWantedSha256); + str_format(aWanted, sizeof(aWanted), "sha256=%s ", aWantedSha256); } - else - { - str_format(aWanted, sizeof(aWanted), "crc=%08x", WantedCrc); - } - - str_format(aBuf, sizeof(aBuf), "loading map, map=%s wanted %s", pMapName, aWanted); + str_format(aBuf, sizeof(aBuf), "loading map, map=%s wanted %scrc=%08x", pMapName, aWanted, WantedCrc); m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf); SetState(IClient::STATE_LOADING); @@ -1245,20 +1265,19 @@ const char *CClient::LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedS return pError; // try the downloaded maps + FormatMapDownloadFilename(pMapName, pWantedSha256, WantedCrc, false, aBuf, sizeof(aBuf)); + pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); + if(!pError) + return pError; + + // backward compatibility with old names if(pWantedSha256) { - str_format(aBuf, sizeof(aBuf), "downloadedmaps/%s_%s.map", pMapName, aWantedSha256); - } - else - { - str_format(aBuf, sizeof(aBuf), "downloadedmaps/%s_%08x.map", pMapName, WantedCrc); + FormatMapDownloadFilename(pMapName, 0, WantedCrc, false, aBuf, sizeof(aBuf)); pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); if(!pError) return pError; } - pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); - if(!pError) - return pError; // search for the map within subfolders char aFilename[128]; @@ -1512,28 +1531,6 @@ bool CClient::ShouldSendChatTimeoutCodeHeuristic() return IsDDNet(&m_CurrentServerInfo); } -static void FormatMapDownloadFilename(const char *pName, SHA256_DIGEST *pSha256, int Crc, bool Temp, char *pBuffer, int BufferSize) -{ - char aHash[SHA256_MAXSTRSIZE]; - if(pSha256) - { - sha256_str(*pSha256, aHash, sizeof(aHash)); - } - else - { - str_format(aHash, sizeof(aHash), "%08x", Crc); - } - - if(Temp) - { - str_format(pBuffer, BufferSize, "%s_%s.map.%d.tmp", pName, aHash, pid()); - } - else - { - str_format(pBuffer, BufferSize, "%s_%s.map", pName, aHash); - } -} - static CServerCapabilities GetServerCapabilities(int Version, int Flags) { CServerCapabilities Result; @@ -1664,16 +1661,18 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } else { - char aFilename[256]; - FormatMapDownloadFilename(pMap, pMapSha256, MapCrc, false, aFilename, sizeof(aFilename)); + if(m_MapdownloadFileTemp) + { + io_close(m_MapdownloadFileTemp); + Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE); + } - char aTempFilename[256]; - FormatMapDownloadFilename(pMap, pMapSha256, MapCrc, true, aTempFilename, sizeof(aTempFilename)); - - str_format(m_aMapdownloadFilename, sizeof(m_aMapdownloadFilename), "downloadedmaps/%s", aTempFilename); + // start map download + FormatMapDownloadFilename(pMap, pMapSha256, MapCrc, false, m_aMapdownloadFilename, sizeof(m_aMapdownloadFilename)); + FormatMapDownloadFilename(pMap, pMapSha256, MapCrc, true, m_aMapdownloadFilenameTemp, sizeof(m_aMapdownloadFilenameTemp)); char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "starting to download map to '%s'", m_aMapdownloadFilename); + str_format(aBuf, sizeof(aBuf), "starting to download map to '%s'", m_aMapdownloadFilenameTemp); m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", aBuf); m_MapdownloadChunk = 0; @@ -1691,11 +1690,11 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) { char aUrl[256]; char aEscaped[256]; - EscapeUrl(aEscaped, sizeof(aEscaped), aFilename); + EscapeUrl(aEscaped, sizeof(aEscaped), m_aMapdownloadFilename + 15); // cut off downloadedmaps/ bool UseConfigUrl = str_comp(g_Config.m_ClMapDownloadUrl, "https://maps2.ddnet.tw") != 0 || m_aMapDownloadUrl[0] == '\0'; str_format(aUrl, sizeof(aUrl), "%s/%s", UseConfigUrl ? g_Config.m_ClMapDownloadUrl : m_aMapDownloadUrl, aEscaped); - m_pMapdownloadTask = std::make_shared(Storage(), aUrl, m_aMapdownloadFilename, IStorage::TYPE_SAVE, CTimeout{g_Config.m_ClMapDownloadConnectTimeoutMs, g_Config.m_ClMapDownloadLowSpeedLimit, g_Config.m_ClMapDownloadLowSpeedTime}); + m_pMapdownloadTask = std::make_shared(Storage(), aUrl, m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE, CTimeout{g_Config.m_ClMapDownloadConnectTimeoutMs, g_Config.m_ClMapDownloadLowSpeedLimit, g_Config.m_ClMapDownloadLowSpeedTime}); Engine()->AddJob(m_pMapdownloadTask); } else @@ -1712,19 +1711,19 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) const unsigned char *pData = Unpacker.GetRaw(Size); // check for errors - if(Unpacker.Error() || Size <= 0 || MapCRC != m_MapdownloadCrc || Chunk != m_MapdownloadChunk || !m_MapdownloadFile) + if(Unpacker.Error() || Size <= 0 || MapCRC != m_MapdownloadCrc || Chunk != m_MapdownloadChunk || !m_MapdownloadFileTemp) return; - io_write(m_MapdownloadFile, pData, Size); + io_write(m_MapdownloadFileTemp, pData, Size); m_MapdownloadAmount += Size; if(Last) { - if(m_MapdownloadFile) + if(m_MapdownloadFileTemp) { - io_close(m_MapdownloadFile); - m_MapdownloadFile = 0; + io_close(m_MapdownloadFileTemp); + m_MapdownloadFileTemp = 0; } FinishMapDownload(); } @@ -2335,7 +2334,7 @@ void CClient::ResetMapDownload() m_pMapdownloadTask->Abort(); m_pMapdownloadTask = NULL; } - m_MapdownloadFile = 0; + m_MapdownloadFileTemp = 0; m_MapdownloadAmount = 0; } @@ -2348,18 +2347,11 @@ void CClient::FinishMapDownload() m_MapdownloadTotalsize = -1; SHA256_DIGEST *pSha256 = m_MapdownloadSha256Present ? &m_MapdownloadSha256 : 0; - char aTmp[MAX_PATH_LENGTH]; - char aMapFileTemp[MAX_PATH_LENGTH]; - char aMapFile[MAX_PATH_LENGTH]; - FormatMapDownloadFilename(m_aMapdownloadName, pSha256, m_MapdownloadCrc, true, aTmp, sizeof(aTmp)); - str_format(aMapFileTemp, sizeof(aMapFileTemp), "downloadedmaps/%s", aTmp); - FormatMapDownloadFilename(m_aMapdownloadName, pSha256, m_MapdownloadCrc, false, aTmp, sizeof(aTmp)); - str_format(aMapFile, sizeof(aMapFileTemp), "downloadedmaps/%s", aTmp); - - Storage()->RenameFile(aMapFileTemp, aMapFile, IStorage::TYPE_SAVE); + Storage()->RemoveFile(m_aMapdownloadFilename, IStorage::TYPE_SAVE); + Storage()->RenameFile(m_aMapdownloadFilenameTemp, m_aMapdownloadFilename, IStorage::TYPE_SAVE); // load map - pError = LoadMap(m_aMapdownloadName, aMapFile, pSha256, m_MapdownloadCrc); + pError = LoadMap(m_aMapdownloadName, m_aMapdownloadFilename, pSha256, m_MapdownloadCrc); if(!pError) { ResetMapDownload(); @@ -2374,10 +2366,11 @@ void CClient::FinishMapDownload() } else { - if(m_MapdownloadFile) + if(m_MapdownloadFileTemp) { - io_close(m_MapdownloadFile); - m_MapdownloadFile = 0; + io_close(m_MapdownloadFileTemp); + m_MapdownloadFileTemp = 0; + Storage()->RemoveFile(m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE); } ResetMapDownload(); DisconnectWithReason(pError); diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 616df0204..dbbac0d88 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -180,8 +180,9 @@ class CClient : public IClient, public CDemoPlayer::IListener // map download std::shared_ptr m_pMapdownloadTask; char m_aMapdownloadFilename[256]; + char m_aMapdownloadFilenameTemp[256]; char m_aMapdownloadName[256]; - IOHANDLE m_MapdownloadFile; + IOHANDLE m_MapdownloadFileTemp; int m_MapdownloadChunk; int m_MapdownloadCrc; int m_MapdownloadAmount;