From a178e324466ae4fc512043fd1c71908117696f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 16:01:41 +0100 Subject: [PATCH 1/7] Add IStorage::FindFile variant to check hashes but not size --- src/engine/shared/storage.cpp | 31 ++++++++++++++++++++++++++----- src/engine/storage.h | 1 + src/test/storage.cpp | 12 ++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/engine/shared/storage.cpp b/src/engine/shared/storage.cpp index 993f58bf67..cb70460806 100644 --- a/src/engine/shared/storage.cpp +++ b/src/engine/shared/storage.cpp @@ -427,7 +427,8 @@ class CStorage : public IStorage const SHA256_DIGEST *m_pWantedSha256; unsigned m_WantedCrc; unsigned m_WantedSize; - bool m_CheckHashAndSize; + bool m_CheckHash; + bool m_CheckSize; }; static int FindFileCallback(const char *pName, int IsDir, int Type, void *pUser) @@ -452,13 +453,15 @@ class CStorage : public IStorage // found the file str_format(Data.m_pBuffer, Data.m_BufferSize, "%s/%s", Data.m_pPath, Data.m_pFilename); - if(Data.m_CheckHashAndSize) + if(Data.m_CheckHash || Data.m_CheckSize) { // check crc and size SHA256_DIGEST Sha256; unsigned Crc = 0; unsigned Size = 0; - if(!Data.m_pStorage->GetHashAndSize(Data.m_pBuffer, Type, &Sha256, &Crc, &Size) || (Data.m_pWantedSha256 && Sha256 != *Data.m_pWantedSha256) || Crc != Data.m_WantedCrc || Size != Data.m_WantedSize) + if(!Data.m_pStorage->GetHashAndSize(Data.m_pBuffer, Type, &Sha256, &Crc, &Size) + || (Data.m_CheckHash && ((Data.m_pWantedSha256 && Sha256 != *Data.m_pWantedSha256) || Crc != Data.m_WantedCrc)) + || (Data.m_CheckSize && Size != Data.m_WantedSize)) { Data.m_pBuffer[0] = 0; return 0; @@ -510,7 +513,24 @@ class CStorage : public IStorage Data.m_pWantedSha256 = 0; Data.m_WantedCrc = 0; Data.m_WantedSize = 0; - Data.m_CheckHashAndSize = false; + Data.m_CheckHash = false; + Data.m_CheckSize = false; + return FindFileImpl(Type, &Data); + } + + virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize, const SHA256_DIGEST *pWantedSha256, unsigned WantedCrc) + { + CFindCBData Data; + Data.m_pStorage = this; + Data.m_pFilename = pFilename; + Data.m_pPath = pPath; + Data.m_pBuffer = pBuffer; + Data.m_BufferSize = BufferSize; + Data.m_pWantedSha256 = pWantedSha256; + Data.m_WantedCrc = WantedCrc; + Data.m_WantedSize = 0; + Data.m_CheckHash = true; + Data.m_CheckSize = false; return FindFileImpl(Type, &Data); } @@ -525,7 +545,8 @@ class CStorage : public IStorage Data.m_pWantedSha256 = pWantedSha256; Data.m_WantedCrc = WantedCrc; Data.m_WantedSize = WantedSize; - Data.m_CheckHashAndSize = true; + Data.m_CheckHash = true; + Data.m_CheckSize = true; return FindFileImpl(Type, &Data); } diff --git a/src/engine/storage.h b/src/engine/storage.h index 1d7641270f..d388ea8579 100644 --- a/src/engine/storage.h +++ b/src/engine/storage.h @@ -28,6 +28,7 @@ class IStorage : public IInterface virtual bool ReadFile(const char *pFilename, int Type, void **ppResult, unsigned *pResultLen) = 0; virtual char *ReadFileStr(const char *pFilename, int Type) = 0; virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize) = 0; + virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize, const SHA256_DIGEST *pWantedSha256, unsigned WantedCrc) = 0; virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize, const SHA256_DIGEST *pWantedSha256, unsigned WantedCrc, unsigned WantedSize) = 0; virtual bool RemoveFile(const char *pFilename, int Type) = 0; virtual bool RenameFile(const char* pOldFilename, const char* pNewFilename, int Type) = 0; diff --git a/src/test/storage.cpp b/src/test/storage.cpp index 995c8df78e..2da9756656 100644 --- a/src/test/storage.cpp +++ b/src/test/storage.cpp @@ -32,6 +32,12 @@ TEST(Storage, FindFile) EXPECT_TRUE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), &Sha256, 0x3bb935c6, 5)); EXPECT_STREQ(aFound, aFilenameWithDot); + EXPECT_TRUE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), 0, 0x3bb935c6)); + EXPECT_STREQ(aFound, aFilenameWithDot); + + EXPECT_TRUE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), &Sha256, 0x3bb935c6)); + EXPECT_STREQ(aFound, aFilenameWithDot); + EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), 0, 0, 0)); EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), 0, 0x3bb935c6, 0)); EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), 0, 0, 5)); @@ -41,5 +47,11 @@ TEST(Storage, FindFile) EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), &WrongSha256, 0x3bb935c6, 5)); EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), &SHA256_ZEROED, 0x3bb935c6, 5)); + EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), 0, 0)); + EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), 0, 0x3bb935c5)); + + EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), &WrongSha256, 0x3bb935c6)); + EXPECT_FALSE(pStorage->FindFile(Info.m_aFilename, ".", IStorage::TYPE_ALL, aFound, sizeof(aFound), &SHA256_ZEROED, 0x3bb935c6)); + EXPECT_TRUE(pStorage->RemoveFile(Info.m_aFilename, IStorage::TYPE_SAVE)); } From 6014360d74b6047ac97b32705d6fa8ac4e7d9d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 21:52:13 +0100 Subject: [PATCH 2/7] Check hashes when recursively searching map in client/demo recorder: If the first file found with the specified name does not have the correct hashes, the search would otherwise stop instead of continuing in other subfolders. --- src/engine/client/client.cpp | 4 ++-- src/engine/shared/demo.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index e1df6ef33f..5f3b897561 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -912,9 +912,9 @@ const char *CClient::LoadMapSearch(const char *pMapName, const SHA256_DIGEST *pW } // search for the map within subfolders - char aFilename[128]; + char aFilename[IO_MAX_PATH_LENGTH]; str_format(aFilename, sizeof(aFilename), "%s.map", pMapName); - if(Storage()->FindFile(aFilename, "maps", IStorage::TYPE_ALL, aBuf, sizeof(aBuf))) + if(Storage()->FindFile(aFilename, "maps", IStorage::TYPE_ALL, aBuf, sizeof(aBuf), pWantedSha256, WantedCrc)) pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); return pError; diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index 4df8d08b3f..5ec428dee7 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -43,7 +43,7 @@ int CDemoRecorder::Start(const char *pFilename, const char *pNetVersion, const c } // open mapfile - char aMapFilename[128]; + char aMapFilename[IO_MAX_PATH_LENGTH]; // try the normal maps folder str_format(aMapFilename, sizeof(aMapFilename), "maps/%s.map", pMap); IOHANDLE MapFile = m_pStorage->OpenFile(aMapFilename, IOFLAG_READ, IStorage::TYPE_ALL, 0, 0, CDataFileReader::CheckSha256, &Sha256); @@ -66,8 +66,8 @@ int CDemoRecorder::Start(const char *pFilename, const char *pNetVersion, const c // search for the map within subfolders char aBuf[IO_MAX_PATH_LENGTH]; str_format(aMapFilename, sizeof(aMapFilename), "%s.map", pMap); - if(m_pStorage->FindFile(aMapFilename, "maps", IStorage::TYPE_ALL, aBuf, sizeof(aBuf))) - MapFile = m_pStorage->OpenFile(aBuf, IOFLAG_READ, IStorage::TYPE_ALL, 0, 0, CDataFileReader::CheckSha256, &Sha256); + if(m_pStorage->FindFile(aMapFilename, "maps", IStorage::TYPE_ALL, aBuf, sizeof(aBuf), &Sha256, Crc)) + MapFile = m_pStorage->OpenFile(aBuf, IOFLAG_READ, IStorage::TYPE_ALL); } if(!MapFile) { From e0f675001d8f26205e55638564c6a91c05aa793d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 16:34:44 +0100 Subject: [PATCH 3/7] Extract CServer::DemoRecorder_Start method (same as in CClient) --- src/engine/server.h | 1 + src/engine/server/server.cpp | 33 +++++++++++++++++++-------------- src/engine/server/server.h | 1 + 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/engine/server.h b/src/engine/server.h index 6ac20abbf4..880c5a979f 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -66,6 +66,7 @@ class IServer : public IInterface virtual void Kick(int ClientID, const char *pReason) = 0; virtual void ChangeMap(const char *pMap) = 0; + virtual void DemoRecorder_Start(const char *pFilename, bool WithTimestamp) = 0; virtual void DemoRecorder_HandleAutoStart() = 0; virtual bool DemoRecorder_IsRecording() = 0; }; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 50e6dfeafe..5009e38e6f 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1605,17 +1605,27 @@ void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser) } } +void CServer::DemoRecorder_Start(const char *pFilename, bool WithTimestamp) +{ + char aFilename[IO_MAX_PATH_LENGTH]; + if(WithTimestamp) + { + char aDate[20]; + str_timestamp(aDate, sizeof(aDate)); + str_format(aFilename, sizeof(aFilename), "demos/%s_%s.demo", pFilename, aDate); + } + else + str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pFilename); + m_DemoRecorder.Start(aFilename, GameServer()->NetVersion(), m_aCurrentMap, m_CurrentMapSha256, m_CurrentMapCrc, "server"); +} + void CServer::DemoRecorder_HandleAutoStart() { if(Config()->m_SvAutoDemoRecord) { if(m_DemoRecorder.IsRecording()) m_DemoRecorder.Stop(); - char aFilename[128]; - char aDate[20]; - str_timestamp(aDate, sizeof(aDate)); - str_format(aFilename, sizeof(aFilename), "demos/%s_%s.demo", "auto/autorecord", aDate); - m_DemoRecorder.Start(aFilename, GameServer()->NetVersion(), m_aCurrentMap, m_CurrentMapSha256, m_CurrentMapCrc, "server"); + DemoRecorder_Start("auto/autorecord", true); if(Config()->m_SvAutoDemoMax) { // clean up auto recorded demos @@ -1632,17 +1642,12 @@ bool CServer::DemoRecorder_IsRecording() void CServer::ConRecord(IConsole::IResult *pResult, void *pUser) { - CServer* pServer = (CServer *)pUser; - char aFilename[128]; + CServer *pServer = (CServer *)pUser; + if(pResult->NumArguments()) - str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pResult->GetString(0)); + pServer->DemoRecorder_Start(pResult->GetString(0), false); else - { - char aDate[20]; - str_timestamp(aDate, sizeof(aDate)); - str_format(aFilename, sizeof(aFilename), "demos/demo_%s.demo", aDate); - } - pServer->m_DemoRecorder.Start(aFilename, pServer->GameServer()->NetVersion(), pServer->m_aCurrentMap, pServer->m_CurrentMapSha256, pServer->m_CurrentMapCrc, "server"); + pServer->DemoRecorder_Start("demo", true); } void CServer::ConStopRecord(IConsole::IResult *pResult, void *pUser) diff --git a/src/engine/server/server.h b/src/engine/server/server.h index ac43b2eb62..782d82f7ae 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -200,6 +200,7 @@ class CServer : public IServer void Kick(int ClientID, const char *pReason); + void DemoRecorder_Start(const char *pFilename, bool WithTimestamp); void DemoRecorder_HandleAutoStart(); bool DemoRecorder_IsRecording(); From 9023b64c023257a291c0dbce5a940c0e736a2fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 16:41:48 +0100 Subject: [PATCH 4/7] Extract CServer::DemoRecorder_Stop method (same as in CClient) --- src/engine/server.h | 1 + src/engine/server/server.cpp | 14 +++++++++----- src/engine/server/server.h | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/engine/server.h b/src/engine/server.h index 880c5a979f..26772f5378 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -68,6 +68,7 @@ class IServer : public IInterface virtual void DemoRecorder_Start(const char *pFilename, bool WithTimestamp) = 0; virtual void DemoRecorder_HandleAutoStart() = 0; + virtual void DemoRecorder_Stop(bool ErrorIfNotRecording = false) = 0; virtual bool DemoRecorder_IsRecording() = 0; }; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 5009e38e6f..fa2e438e1d 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1243,8 +1243,7 @@ int CServer::LoadMap(const char *pMapName) return 0; // stop recording when we change map - if(m_DemoRecorder.IsRecording()) - m_DemoRecorder.Stop(); + DemoRecorder_Stop(); // reinit snapshot ids m_IDPool.TimeoutIDs(); @@ -1623,8 +1622,7 @@ void CServer::DemoRecorder_HandleAutoStart() { if(Config()->m_SvAutoDemoRecord) { - if(m_DemoRecorder.IsRecording()) - m_DemoRecorder.Stop(); + DemoRecorder_Stop(); DemoRecorder_Start("auto/autorecord", true); if(Config()->m_SvAutoDemoMax) { @@ -1635,6 +1633,12 @@ void CServer::DemoRecorder_HandleAutoStart() } } +void CServer::DemoRecorder_Stop(bool ErrorIfNotRecording) +{ + if(ErrorIfNotRecording || m_DemoRecorder.IsRecording()) + m_DemoRecorder.Stop(); +} + bool CServer::DemoRecorder_IsRecording() { return m_DemoRecorder.IsRecording(); @@ -1652,7 +1656,7 @@ void CServer::ConRecord(IConsole::IResult *pResult, void *pUser) void CServer::ConStopRecord(IConsole::IResult *pResult, void *pUser) { - ((CServer *)pUser)->m_DemoRecorder.Stop(); + ((CServer *)pUser)->DemoRecorder_Stop(true); } void CServer::ConMapReload(IConsole::IResult *pResult, void *pUser) diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 782d82f7ae..17feecfc5a 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -202,6 +202,7 @@ class CServer : public IServer void DemoRecorder_Start(const char *pFilename, bool WithTimestamp); void DemoRecorder_HandleAutoStart(); + void DemoRecorder_Stop(bool ErrorIfNotRecording = false); bool DemoRecorder_IsRecording(); int64 TickStartTime(int Tick); From 7728a0368441d4b87e9a6c48bb60a7921fd74868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 17:05:44 +0100 Subject: [PATCH 5/7] Extract duplicate filename format code into demo recorder --- src/engine/client/client.cpp | 13 +------------ src/engine/server/server.cpp | 11 +---------- src/engine/shared/demo.cpp | 18 ++++++++++++++---- src/engine/shared/demo.h | 2 +- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 5f3b897561..8d769dd275 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2339,18 +2339,7 @@ void CClient::DemoRecorder_Start(const char *pFilename, bool WithTimestamp) if(State() != IClient::STATE_ONLINE) m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demorec/record", "client is not online"); else - { - char aFilename[128]; - if(WithTimestamp) - { - char aDate[20]; - str_timestamp(aDate, sizeof(aDate)); - str_format(aFilename, sizeof(aFilename), "demos/%s_%s.demo", pFilename, aDate); - } - else - str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pFilename); - m_DemoRecorder.Start(aFilename, GameClient()->NetVersion(), m_aCurrentMap, m_CurrentMapSha256, m_CurrentMapCrc, "client"); - } + m_DemoRecorder.Start(pFilename, WithTimestamp, GameClient()->NetVersion(), m_aCurrentMap, m_CurrentMapSha256, m_CurrentMapCrc, "client"); } void CClient::DemoRecorder_HandleAutoStart() diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index fa2e438e1d..620c96300e 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1606,16 +1606,7 @@ void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser) void CServer::DemoRecorder_Start(const char *pFilename, bool WithTimestamp) { - char aFilename[IO_MAX_PATH_LENGTH]; - if(WithTimestamp) - { - char aDate[20]; - str_timestamp(aDate, sizeof(aDate)); - str_format(aFilename, sizeof(aFilename), "demos/%s_%s.demo", pFilename, aDate); - } - else - str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pFilename); - m_DemoRecorder.Start(aFilename, GameServer()->NetVersion(), m_aCurrentMap, m_CurrentMapSha256, m_CurrentMapCrc, "server"); + m_DemoRecorder.Start(pFilename, WithTimestamp, GameServer()->NetVersion(), m_aCurrentMap, m_CurrentMapSha256, m_CurrentMapCrc, "server"); } void CServer::DemoRecorder_HandleAutoStart() diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index 5ec428dee7..755f0c5ecf 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -33,7 +33,7 @@ void CDemoRecorder::Init(class IConsole *pConsole, class IStorage *pStorage) } // Record -int CDemoRecorder::Start(const char *pFilename, const char *pNetVersion, const char *pMap, SHA256_DIGEST Sha256, unsigned Crc, const char *pType) +int CDemoRecorder::Start(const char *pFilename, bool WithTimestamp, const char *pNetVersion, const char *pMap, SHA256_DIGEST Sha256, unsigned Crc, const char *pType) { CDemoHeader Header; if(m_File) @@ -77,13 +77,23 @@ int CDemoRecorder::Start(const char *pFilename, const char *pNetVersion, const c return -1; } - IOHANDLE DemoFile = m_pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE); + char aDemoFilename[IO_MAX_PATH_LENGTH]; + if(WithTimestamp) + { + char aDate[20]; + str_timestamp(aDate, sizeof(aDate)); + str_format(aDemoFilename, sizeof(aDemoFilename), "demos/%s_%s.demo", pFilename, aDate); + } + else + str_format(aDemoFilename, sizeof(aDemoFilename), "demos/%s.demo", pFilename); + + IOHANDLE DemoFile = m_pStorage->OpenFile(aDemoFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE); if(!DemoFile) { io_close(MapFile); MapFile = 0; char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "Unable to open '%s' for recording", pFilename); + str_format(aBuf, sizeof(aBuf), "Unable to open '%s' for recording", aDemoFilename); m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf); return -1; } @@ -121,7 +131,7 @@ int CDemoRecorder::Start(const char *pFilename, const char *pNetVersion, const c m_NumTimelineMarkers = 0; char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "Recording to '%s'", pFilename); + str_format(aBuf, sizeof(aBuf), "Recording to '%s'", aDemoFilename); m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf); m_File = DemoFile; diff --git a/src/engine/shared/demo.h b/src/engine/shared/demo.h index e4247be7c2..53e1157017 100644 --- a/src/engine/shared/demo.h +++ b/src/engine/shared/demo.h @@ -29,7 +29,7 @@ class CDemoRecorder : public IDemoRecorder CDemoRecorder(class CSnapshotDelta *pSnapshotDelta); void Init(class IConsole *pConsole, class IStorage *pStorage); - int Start(const char *pFilename, const char *pNetversion, const char *pMap, SHA256_DIGEST MapSha256, unsigned MapCrc, const char *pType); + int Start(const char *pFilename, bool WithTimestamp, const char *pNetversion, const char *pMap, SHA256_DIGEST MapSha256, unsigned MapCrc, const char *pType); int Stop(); void AddDemoMarker(); From 11816806c8722826087e95e20dec5ad8c349ec8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 21:22:34 +0100 Subject: [PATCH 6/7] Add CDataFileReader::CheckCrc --- src/engine/shared/datafile.cpp | 25 +++++++++++++++++++++---- src/engine/shared/datafile.h | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/engine/shared/datafile.cpp b/src/engine/shared/datafile.cpp index d0b88376f3..7084bc7966 100644 --- a/src/engine/shared/datafile.cpp +++ b/src/engine/shared/datafile.cpp @@ -481,12 +481,11 @@ unsigned CDataFileReader::Crc() const bool CDataFileReader::CheckSha256(IOHANDLE Handle, const void *pSha256) { - // read the hash of the file SHA256_CTX Sha256Ctx; sha256_init(&Sha256Ctx); unsigned char aBuffer[64*1024]; - - while(1) + + while(true) { unsigned Bytes = io_read(Handle, aBuffer, sizeof(aBuffer)); if(Bytes == 0) @@ -497,7 +496,25 @@ bool CDataFileReader::CheckSha256(IOHANDLE Handle, const void *pSha256) io_seek(Handle, 0, IOSEEK_START); SHA256_DIGEST Sha256 = sha256_finish(&Sha256Ctx); - return !sha256_comp(*(const SHA256_DIGEST *)pSha256, Sha256); + return *(const SHA256_DIGEST *)pSha256 == Sha256; +} + +bool CDataFileReader::CheckCrc(IOHANDLE Handle, const void *pCrc) +{ + unsigned Crc = crc32(0L, 0x0, 0); + unsigned char aBuffer[64*1024]; + + while(true) + { + unsigned Bytes = io_read(Handle, aBuffer, sizeof(aBuffer)); + if(Bytes == 0) + break; + Crc = crc32(Crc, aBuffer, Bytes); + } + + io_seek(Handle, 0, IOSEEK_START); + + return *(const unsigned *)pCrc == Crc; } diff --git a/src/engine/shared/datafile.h b/src/engine/shared/datafile.h index 98529e5f85..38f2ea3f2f 100644 --- a/src/engine/shared/datafile.h +++ b/src/engine/shared/datafile.h @@ -39,6 +39,7 @@ class CDataFileReader unsigned Crc() const; static bool CheckSha256(IOHANDLE Handle, const void *pSha256); + static bool CheckCrc(IOHANDLE Handle, const void *pCrc); }; // write access From 0e312c8db91b335d5e9b9de9fee3f2c758417625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Mar 2022 21:49:10 +0100 Subject: [PATCH 7/7] Search maps folder and subfolders in demo player map search --- src/engine/shared/demo.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index 755f0c5ecf..ba763ee519 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -685,14 +685,30 @@ const char *CDemoPlayer::Load(const char *pFilename, int StorageType, const char m_DemoType = DEMOTYPE_INVALID; // read map - unsigned MapSize = bytes_be_to_uint(m_Info.m_Header.m_aMapSize); + const unsigned MapSize = bytes_be_to_uint(m_Info.m_Header.m_aMapSize); + const unsigned Crc = bytes_be_to_uint(m_Info.m_Header.m_aMapCrc); // check if we already have the map - // TODO: improve map checking (maps folder, check crc) - unsigned Crc = bytes_be_to_uint(m_Info.m_Header.m_aMapCrc); - char aMapFilename[128]; - str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", m_Info.m_Header.m_aMapName, Crc); - IOHANDLE MapFile = m_pStorage->OpenFile(aMapFilename, IOFLAG_READ, IStorage::TYPE_ALL); + // TODO: add map sha256 to demo file and check for correct sha256 if available instead of crc + char aMapFilename[IO_MAX_PATH_LENGTH]; + char aMapFilenameOutput[IO_MAX_PATH_LENGTH]; + // try the normal maps folder + str_format(aMapFilename, sizeof(aMapFilename), "maps/%s.map", m_Info.m_Header.m_aMapName); + IOHANDLE MapFile = m_pStorage->OpenFile(aMapFilename, IOFLAG_READ, IStorage::TYPE_ALL, 0, 0, CDataFileReader::CheckCrc, &Crc); + if(!MapFile) + { + // try the downloaded maps (crc) + str_format(aMapFilenameOutput, sizeof(aMapFilenameOutput), "downloadedmaps/%s_%08x.map", m_Info.m_Header.m_aMapName, Crc); + MapFile = m_pStorage->OpenFile(aMapFilenameOutput, IOFLAG_READ, IStorage::TYPE_ALL); + } + if(!MapFile) + { + // search for the map within subfolders + char aBuf[IO_MAX_PATH_LENGTH]; + str_format(aMapFilename, sizeof(aMapFilename), "%s.map", m_Info.m_Header.m_aMapName); + if(m_pStorage->FindFile(aMapFilename, "maps", IStorage::TYPE_ALL, aBuf, sizeof(aBuf), 0, Crc)) + MapFile = m_pStorage->OpenFile(aBuf, IOFLAG_READ, IStorage::TYPE_ALL); + } if(MapFile) { @@ -706,7 +722,7 @@ const char *CDemoPlayer::Load(const char *pFilename, int StorageType, const char io_read(m_File, pMapData, MapSize); // save map - MapFile = m_pStorage->OpenFile(aMapFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE); + MapFile = m_pStorage->OpenFile(aMapFilenameOutput, IOFLAG_WRITE, IStorage::TYPE_SAVE); io_write(MapFile, pMapData, MapSize); io_close(MapFile);