diff --git a/scripts/integration_test.sh b/scripts/integration_test.sh index 364d5d942..de517eda6 100755 --- a/scripts/integration_test.sh +++ b/scripts/integration_test.sh @@ -159,6 +159,7 @@ function wait_for_fifo() { done } +echo "[*] launch server" $tool ../DDNet-Server \ "sv_input_fifo server.fifo; sv_rcon_password rcon; @@ -168,6 +169,7 @@ $tool ../DDNet-Server \ sv_register 0; sv_port $port" > stdout_server.txt 2> stderr_server.txt || fail server "$?" & +echo "[*] launch client 1" $tool ../DDNet \ "cl_input_fifo client1.fifo; player_name client1; @@ -179,12 +181,18 @@ $tool ../DDNet \ if [ "$arg_valgrind_memcheck" == "1" ]; then wait_for_fifo client1.fifo 120 - sleep 1 + sleep 20 else wait_for_fifo client1.fifo 50 sleep 1 fi +echo "[*] start demo recording" +echo "record server" > server.fifo +echo "record client1" > client1.fifo +sleep 1 + +echo "[*] launch client 2" $tool ../DDNet \ "cl_input_fifo client2.fifo; player_name client2; @@ -225,6 +233,7 @@ say "/mc ;saytime" EOF sleep 1 + echo "[*] test rcon commands" tr -d '\n' > client1.fifo << EOF rcon say hello from admin; @@ -235,10 +244,33 @@ muteid 1 900 spam; unban_all; EOF sleep 1 -echo "[*] test map change" -echo "rcon sv_map Tutorial" > client1.fifo + +echo "[*] stop demo recording" +echo "stoprecord" > server.fifo +echo "stoprecord" > client1.fifo sleep 1 +echo "[*] test map change" +echo "rcon sv_map Tutorial" > client1.fifo +if [ "$arg_valgrind_memcheck" == "1" ]; then + sleep 30 +else + sleep 15 +fi + +echo "[*] play demos" +echo "play demos/server.demo" > client1.fifo +echo "play demos/client1.demo" > client2.fifo +if [ "$arg_valgrind_memcheck" == "1" ]; then + sleep 20 +else + sleep 5 +fi + +# Kill all processes first so all outputs are fully written +kill_all +wait +sleep 1 # TODO: remove the first grep after https://github.com/ddnet/ddnet/pull/5036 is merged if ! grep -qE '^\[[0-9]{4}-[0-9]{2}-[0-9]{2} ([0-9]{2}:){2}[0-9]{2}\]\[chat\]: 0:-2:client1: hello world$' server.log && \ @@ -247,6 +279,7 @@ then touch fail_chat.txt echo "[-] Error: chat message not found in server log" fi + if ! grep -q 'cmdlist' client1.log || \ ! grep -q 'pause' client1.log || \ ! grep -q 'rank' client1.log || \ @@ -262,10 +295,16 @@ then echo "[-] Error: admin message not found in server log" fi -kill_all -wait - -sleep 1 +if ! grep -q "\[demo_player\]: Stopped playback" client1.log +then + touch fail_demo_server.txt + echo "[-] Error: demo playback of server demo in client 1 was not started/finished" +fi +if ! grep -q "\[demo_player\]: Stopped playback" client2.log +then + touch fail_demo_client.txt + echo "[-] Error: demo playback of client demo in client 2 was not started/finished" +fi ranks="$(sqlite3 ddnet-server.sqlite < <(echo "select * from record_race;"))" num_ranks="$(echo "$ranks" | wc -l | xargs)" diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 209fb312c..dc84576bf 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1299,7 +1299,6 @@ static void FormatMapDownloadFilename(const char *pName, const SHA256_DIGEST *pS const char *CClient::LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedSha256, int WantedCrc) { - const char *pError = 0; char aBuf[512]; char aWanted[SHA256_MAXSTRSIZE + 16]; aWanted[0] = 0; @@ -1316,15 +1315,15 @@ const char *CClient::LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedS // try the normal maps folder str_format(aBuf, sizeof(aBuf), "maps/%s.map", pMapName); - pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); + const char *pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); if(!pError) - return pError; + return nullptr; // try the downloaded maps FormatMapDownloadFilename(pMapName, pWantedSha256, WantedCrc, false, aBuf, sizeof(aBuf)); pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); if(!pError) - return pError; + return nullptr; // backward compatibility with old names if(pWantedSha256) @@ -1332,16 +1331,22 @@ const char *CClient::LoadMapSearch(const char *pMapName, SHA256_DIGEST *pWantedS FormatMapDownloadFilename(pMapName, 0, WantedCrc, false, aBuf, sizeof(aBuf)); pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); if(!pError) - return pError; + return nullptr; } // search for the map within subfolders 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))) + { pError = LoadMap(pMapName, aBuf, pWantedSha256, WantedCrc); + if(!pError) + return nullptr; + } - return pError; + static char s_aErrorMsg[256]; + str_format(s_aErrorMsg, sizeof(s_aErrorMsg), "Could not find map '%s'", pMapName); + return s_aErrorMsg; } void CClient::ProcessConnlessPacket(CNetChunk *pPacket) @@ -3903,7 +3908,10 @@ const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType) if(pError) { if(!m_DemoPlayer.ExtractMap(Storage())) + { + DisconnectWithReason(pError); return pError; + } Sha = m_DemoPlayer.GetMapInfo()->m_Sha256; pError = LoadMapSearch(pMapInfo->m_aName, &Sha, Crc); diff --git a/src/engine/server.h b/src/engine/server.h index 3dead98ca..4e25b3521 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -229,7 +229,6 @@ public: virtual void ChangeMap(const char *pMap) = 0; virtual void DemoRecorder_HandleAutoStart() = 0; - virtual bool DemoRecorder_IsRecording() = 0; // DDRace diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 3dc212a81..763704e7c 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -799,9 +799,13 @@ int CServer::SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) if(RepackMsg(pMsg, Pack7, true)) return -1; - // write message to demo recorder + // write message to demo recorders if(!(Flags & MSGFLAG_NORECORD)) - m_aDemoRecorder[MAX_CLIENTS].RecordMessage(Pack6.Data(), Pack6.Size()); + { + for(auto &Recorder : m_aDemoRecorder) + if(Recorder.IsRecording()) + Recorder.RecordMessage(Pack6.Data(), Pack6.Size()); + } if(!(Flags & MSGFLAG_NOSEND)) { @@ -837,10 +841,13 @@ int CServer::SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) return 0; } + // write message to demo recorders if(!(Flags & MSGFLAG_NORECORD)) { - m_aDemoRecorder[ClientID].RecordMessage(Pack.Data(), Pack.Size()); - m_aDemoRecorder[MAX_CLIENTS].RecordMessage(Pack.Data(), Pack.Size()); + if(m_aDemoRecorder[ClientID].IsRecording()) + m_aDemoRecorder[ClientID].RecordMessage(Pack.Data(), Pack.Size()); + if(m_aDemoRecorder[MAX_CLIENTS].IsRecording()) + m_aDemoRecorder[MAX_CLIENTS].RecordMessage(Pack.Data(), Pack.Size()); } if(!(Flags & MSGFLAG_NOSEND)) @@ -3252,11 +3259,6 @@ void CServer::DemoRecorder_HandleAutoStart() } } -bool CServer::DemoRecorder_IsRecording() -{ - return m_aDemoRecorder[MAX_CLIENTS].IsRecording(); -} - void CServer::SaveDemo(int ClientID, float Time) { if(IsRecording(ClientID)) @@ -3267,7 +3269,7 @@ void CServer::SaveDemo(int ClientID, float Time) char aOldFilename[IO_MAX_PATH_LENGTH]; char aNewFilename[IO_MAX_PATH_LENGTH]; str_format(aOldFilename, sizeof(aOldFilename), "demos/%s_%d_%d_tmp.demo", m_aCurrentMap, m_NetServer.Address().port, ClientID); - str_format(aNewFilename, sizeof(aNewFilename), "demos/%s_%s_%5.2f.demo", m_aCurrentMap, m_aClients[ClientID].m_aName, Time); + str_format(aNewFilename, sizeof(aNewFilename), "demos/%s_%s_%05.2f.demo", m_aCurrentMap, m_aClients[ClientID].m_aName, Time); Storage()->RenameFile(aOldFilename, aNewFilename, IStorage::TYPE_SAVE); } } diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 7ba34816f..fe943614f 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -287,7 +287,6 @@ public: void Ban(int ClientID, int Seconds, const char *pReason) override; void DemoRecorder_HandleAutoStart() override; - bool DemoRecorder_IsRecording() override; //int Tick() int64_t TickStartTime(int Tick); diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index b0af12c8a..6e1a2b531 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -124,7 +124,9 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con CloseMapFile = true; } - if(MapFile) + if(m_NoMapData) + MapSize = 0; + else if(MapFile) MapSize = io_length(MapFile); // write header diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 628d1e606..9b224aa78 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -3734,7 +3734,7 @@ void CGameContext::OnSnap(int ClientID) { // add tuning to demo CTuningParams StandardTuning; - if(ClientID == -1 && Server()->DemoRecorder_IsRecording() && mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) != 0) + if(Server()->IsRecording(ClientID > -1 ? ClientID : MAX_CLIENTS) && mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) != 0) { CMsgPacker Msg(NETMSGTYPE_SV_TUNEPARAMS); int *pParams = (int *)&m_Tuning;