From a0985314c92cd1422c994f81ec22ab2a9c5dcd07 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 11 Dec 2010 18:55:28 +0100 Subject: [PATCH] made it possible to "recycle" auto recorded demos --- data/languages/bosnian.txt | 9 + data/languages/czech.txt | 9 + data/languages/dutch.txt | 17 +- data/languages/finnish.txt | 9 + data/languages/french.txt | 9 + data/languages/german.txt | 9 + data/languages/italian.txt | 9 + data/languages/polish.txt | 9 + data/languages/portuguese.txt | 9 + data/languages/russian.txt | 9 + data/languages/serbian.txt | 9 + data/languages/swedish.txt | 9 + src/engine/client/client.cpp | 187 +++++++++++++++++- src/engine/client/client.h | 30 +++ src/engine/shared/config_variables.h | 1 + src/game/client/components/menus_settings.cpp | 25 ++- 16 files changed, 351 insertions(+), 8 deletions(-) diff --git a/data/languages/bosnian.txt b/data/languages/bosnian.txt index e8d01b9d8..e871ac536 100644 --- a/data/languages/bosnian.txt +++ b/data/languages/bosnian.txt @@ -510,6 +510,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -696,6 +699,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/czech.txt b/data/languages/czech.txt index 5057e634a..c2e28d272 100644 --- a/data/languages/czech.txt +++ b/data/languages/czech.txt @@ -486,6 +486,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -684,6 +687,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/dutch.txt b/data/languages/dutch.txt index 48fe288f4..9e30566fd 100644 --- a/data/languages/dutch.txt +++ b/data/languages/dutch.txt @@ -1,3 +1,4 @@ + ##### translated strings ##### %d of %d servers, %d players @@ -657,12 +658,12 @@ Reset to defaults Resizes the current Quad based on the aspect ratio of the image == Verkleint/vergroot de huidige quad gebaseerd op de verhouding van de afbeelding. -Right -== Rechts - Rifle == Laser +Right +== Rechts + Rotation of the brush in degrees. Use left mouse button to drag and change the value. Hold shift to be more precise. == Rotatie van de kwast in graden. Linkermuisknop om te slepen en de waarde te veranderen. Shift om meer precies te zijn. @@ -932,4 +933,14 @@ ZO ##### needs translation ##### +Automatically record demos +== + +Max demos +== + +no limit +== + ##### old translations ##### + diff --git a/data/languages/finnish.txt b/data/languages/finnish.txt index de5959f63..9f1af60ce 100644 --- a/data/languages/finnish.txt +++ b/data/languages/finnish.txt @@ -510,6 +510,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -696,6 +699,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/french.txt b/data/languages/french.txt index daf95d825..711a591af 100644 --- a/data/languages/french.txt +++ b/data/languages/french.txt @@ -744,6 +744,9 @@ Alpha value of the envelope Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -816,6 +819,9 @@ Left mouse button to move. Hold shift to move the texture. Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point aswell. Right click to delete. == +Max demos +== + Next Envelope == @@ -933,5 +939,8 @@ Y-axis of the envelope [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/german.txt b/data/languages/german.txt index 041e47122..c514592f9 100644 --- a/data/languages/german.txt +++ b/data/languages/german.txt @@ -933,5 +933,14 @@ ZO ##### needs translation ##### +Automatically record demos +== + +Max demos +== + +no limit +== + ##### old translations ##### diff --git a/data/languages/italian.txt b/data/languages/italian.txt index 139ebccea..08a003d12 100644 --- a/data/languages/italian.txt +++ b/data/languages/italian.txt @@ -480,6 +480,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -681,6 +684,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/polish.txt b/data/languages/polish.txt index a867cccf4..0d1d169f0 100644 --- a/data/languages/polish.txt +++ b/data/languages/polish.txt @@ -792,6 +792,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -852,6 +855,9 @@ Load Load map == +Max demos +== + New folder == @@ -933,5 +939,8 @@ Y-axis of the envelope [HOME] Restore map focus == +no limit +== + ##### old translations ##### diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index 3b4aa4539..e5a27a31e 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -507,6 +507,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -696,6 +699,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/russian.txt b/data/languages/russian.txt index a9017b916..01e601c36 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -804,6 +804,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -858,6 +861,9 @@ Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point Load map == +Max demos +== + New folder == @@ -933,5 +939,8 @@ Y-axis of the envelope [HOME] Restore map focus == +no limit +== + ##### old translations ##### diff --git a/data/languages/serbian.txt b/data/languages/serbian.txt index 8018fb805..8f6c67425 100644 --- a/data/languages/serbian.txt +++ b/data/languages/serbian.txt @@ -510,6 +510,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -696,6 +699,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/data/languages/swedish.txt b/data/languages/swedish.txt index a7d6bbf4a..9d5301e6e 100644 --- a/data/languages/swedish.txt +++ b/data/languages/swedish.txt @@ -480,6 +480,9 @@ Are you sure that you want to delete the demo? Aspect ratio == +Automatically record demos +== + Blue value of the envelope == @@ -681,6 +684,9 @@ Make collision Make external == +Max demos +== + Name: == @@ -933,5 +939,8 @@ ZO [ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. == +no limit +== + ##### old translations ##### diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 7420f0949..ac15d1289 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -3,8 +3,8 @@ #include // qsort #include -#include +#include #include #include @@ -217,6 +217,183 @@ void CSmoothTime::Update(CGraph *pGraph, int64 Target, int TimeLeft, int AdjustD } +bool CFileCollection::IsFilenameValid(const char *pFilename) +{ + if(str_length(pFilename) != m_FileDescLength+TIMESTAMP_LENGTH+m_FileExtLength || + str_comp_num(pFilename, m_aFileDesc, m_FileDescLength) || + str_comp(pFilename+m_FileDescLength+TIMESTAMP_LENGTH, m_aFileExt)) + return false; + + pFilename += m_FileDescLength; + if(pFilename[0] == '_' && + pFilename[1] >= '0' && pFilename[1] <= '9' && + pFilename[2] >= '0' && pFilename[2] <= '9' && + pFilename[3] >= '0' && pFilename[3] <= '9' && + pFilename[4] >= '0' && pFilename[4] <= '9' && + pFilename[5] == '-' && + pFilename[6] >= '0' && pFilename[6] <= '9' && + pFilename[7] >= '0' && pFilename[7] <= '9' && + pFilename[8] == '-' && + pFilename[9] >= '0' && pFilename[9] <= '9' && + pFilename[10] >= '0' && pFilename[10] <= '9' && + pFilename[11] == '_' && + pFilename[12] >= '0' && pFilename[12] <= '9' && + pFilename[13] >= '0' && pFilename[13] <= '9' && + pFilename[14] == '-' && + pFilename[15] >= '0' && pFilename[15] <= '9' && + pFilename[16] >= '0' && pFilename[16] <= '9' && + pFilename[17] == '-' && + pFilename[18] >= '0' && pFilename[18] <= '9' && + pFilename[19] >= '0' && pFilename[19] <= '9') + return true; + + return false; +} + +int64 CFileCollection::ExtractTimestamp(const char *pTimestring) +{ + int64 Timestamp = pTimestring[0]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[1]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[2]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[3]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[5]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[6]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[8]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[9]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[11]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[12]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[14]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[15]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[17]-'0'; Timestamp <<= 4; + Timestamp += pTimestring[18]-'0'; + + return Timestamp; +} + +void CFileCollection::BuildTimestring(int64 Timestamp, char *pTimestring) +{ + pTimestring[19] = 0; + pTimestring[18] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[17] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[16] = '-'; + pTimestring[15] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[14] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[13] = '-'; + pTimestring[12] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[11] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[10] = '_'; + pTimestring[9] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[8] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[7] = '-'; + pTimestring[6] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[5] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[4] = '-'; + pTimestring[3] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[2] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[1] = (Timestamp&0xF)+'0'; Timestamp >>= 4; + pTimestring[0] = (Timestamp&0xF)+'0'; +} + +void CFileCollection::Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries) +{ + mem_zero(m_aTimestamps, sizeof(m_aTimestamps)); + m_NumTimestamps = 0; + m_MaxEntries = clamp(MaxEntries, 1, static_cast(MAX_ENTRIES)); + str_copy(m_aFileDesc, pFileDesc, sizeof(m_aFileDesc)); + m_FileDescLength = str_length(m_aFileDesc); + str_copy(m_aFileExt, pFileExt, sizeof(m_aFileExt)); + m_FileExtLength = str_length(m_aFileExt); + str_copy(m_aPath, pPath, sizeof(m_aPath)); + m_pStorage = pStorage; + + m_pStorage->ListDirectory(IStorage::TYPE_SAVE, m_aPath, FilelistCallback, this); +} + +void CFileCollection::AddEntry(int64 Timestamp) +{ + if(m_NumTimestamps == 0) + { + // empty list + m_aTimestamps[m_NumTimestamps++] = Timestamp; + } + else + { + // remove old file + if(m_NumTimestamps == m_MaxEntries) + { + char aBuf[512]; + char aTimestring[TIMESTAMP_LENGTH]; + BuildTimestring(m_aTimestamps[0], aTimestring); + str_format(aBuf, sizeof(aBuf), "%s/%s_%s%s", m_aPath, m_aFileDesc, aTimestring, m_aFileExt); + m_pStorage->RemoveFile(aBuf, IStorage::TYPE_SAVE); + } + + // add entry to the sorted list + if(m_aTimestamps[0] > Timestamp) + { + // first entry + if(m_NumTimestamps < m_MaxEntries) + { + mem_move(m_aTimestamps+1, m_aTimestamps, m_NumTimestamps*sizeof(int64)); + m_aTimestamps[0] = Timestamp; + ++m_NumTimestamps; + } + } + else if(m_aTimestamps[m_NumTimestamps-1] <= Timestamp) + { + // last entry + if(m_NumTimestamps == m_MaxEntries) + { + mem_move(m_aTimestamps, m_aTimestamps+1, (m_NumTimestamps-1)*sizeof(int64)); + m_aTimestamps[m_NumTimestamps-1] = Timestamp; + } + else + m_aTimestamps[m_NumTimestamps++] = Timestamp; + } + else + { + // middle entry + int Left = 0, Right = m_NumTimestamps-1; + while(Right-Left > 1) + { + int Mid = (Left+Right)/2; + if(m_aTimestamps[Mid] > Timestamp) + Right = Mid; + else + Left = Mid; + } + + if(m_NumTimestamps == m_MaxEntries) + { + mem_move(m_aTimestamps, m_aTimestamps+1, (Right-1)*sizeof(int64)); + m_aTimestamps[Right-1] = Timestamp; + } + else + { + mem_move(m_aTimestamps+Right+1, m_aTimestamps+Right, (m_NumTimestamps-Right)*sizeof(int64)); + m_aTimestamps[Right] = Timestamp; + ++m_NumTimestamps; + } + } + } +} + +void CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser) +{ + CFileCollection *pThis = static_cast(pUser); + + // check for valid file name format + if(IsDir || !pThis->IsFilenameValid(pFilename)) + return; + + // extract the timestamp + int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1); + + // add the entry + pThis->AddEntry(Timestamp); +} + + CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotDelta) { m_pEditor = 0; @@ -1957,7 +2134,15 @@ void CClient::DemoRecorder_Start(const char *pFilename, bool WithTimestamp) void CClient::DemoRecorder_HandleAutoStart() { if(g_Config.m_ClAutoDemoRecord) + { DemoRecorder_Start("auto/autorecord", true); + if(g_Config.m_ClAutoDemoMax) + { + // clean up auto recorded demos + CFileCollection AutoDemos; + AutoDemos.Init(Storage(), "demos/auto", "autorecord", ".demo", g_Config.m_ClAutoDemoMax); + } + } } void CClient::DemoRecorder_Stop() diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 1a35788ba..8486e4814 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -73,6 +73,36 @@ public: }; +class CFileCollection +{ + enum + { + MAX_ENTRIES=1000, + TIMESTAMP_LENGTH=20, // _YYYY-MM-DD_HH-MM-SS + }; + + int64 m_aTimestamps[MAX_ENTRIES]; + int m_NumTimestamps; + int m_MaxEntries; + char m_aFileDesc[128]; + int m_FileDescLength; + char m_aFileExt[32]; + int m_FileExtLength; + char m_aPath[512]; + IStorage *m_pStorage; + + bool IsFilenameValid(const char *pFilename); + int64 ExtractTimestamp(const char *pTimestring); + void BuildTimestring(int64 Timestamp, char *pTimestring); + +public: + void Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries); + void AddEntry(int64 Timestamp); + + static void FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser); +}; + + class CClient : public IClient, public CDemoPlayer::IListner { // needed interfaces diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index ce9b19827..b34e733b0 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -18,6 +18,7 @@ MACRO_CONFIG_INT(ClCpuThrottle, cl_cpu_throttle, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_C MACRO_CONFIG_INT(ClEditor, cl_editor, 0, 0, 1, CFGFLAG_CLIENT, "") MACRO_CONFIG_INT(ClAutoDemoRecord, cl_auto_demo_record, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Automatically record demos") +MACRO_CONFIG_INT(ClAutoDemoMax, cl_auto_demo_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically recorded demos (0 = no limit)") MACRO_CONFIG_INT(ClEventthread, cl_eventthread, 0, 0, 1, CFGFLAG_CLIENT, "Enables the usage of a thread to pump the events") diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 0a3ceca57..b12a0c8d5 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -729,13 +729,30 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) int OldSelected = s_SelectedLanguage; - CUIRect List, Button; + CUIRect List, Button, Label, Left; MainView.HSplitBottom(10.0f, &MainView, 0); - MainView.HSplitBottom(20.0f, &MainView, &Button); + MainView.HSplitBottom(70.0f, &MainView, &Left); + Left.VSplitMid(&Left, 0); + Left.HSplitTop(20.0f, &Button, &Left); MainView.HSplitBottom(20.0f, &List, &MainView); - if(DoButton_CheckBox(&g_Config.m_ClAutoDemoRecord, Localize("Automatically record demos"), g_Config.m_ClAutoDemoRecord, &Button)) - g_Config.m_ClAutoDemoRecord ^= 1; + // auto demo settings + { + if(DoButton_CheckBox(&g_Config.m_ClAutoDemoRecord, Localize("Automatically record demos"), g_Config.m_ClAutoDemoRecord, &Button)) + g_Config.m_ClAutoDemoRecord ^= 1; + + Left.HSplitTop(10.0f, 0, &Left); + Left.VSplitLeft(20.0f, 0, &Left); + Left.HSplitTop(20.0f, &Label, &Button); + Button.VSplitRight(20.0f, &Button, 0); + char aBuf[64]; + if(g_Config.m_ClAutoDemoMax) + str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Max demos"), g_Config.m_ClAutoDemoMax); + else + str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max demos"), Localize("no limit")); + UI()->DoLabel(&Label, aBuf, 13.0f, -1); + g_Config.m_ClAutoDemoMax = static_cast(DoScrollbarH(&g_Config.m_ClAutoDemoMax, &Button, g_Config.m_ClAutoDemoMax/1000.0f)*1000.0f+0.1f); + } UiDoListboxStart(&s_LanguageList , &List, 24.0f, Localize("Language"), "", s_Languages.size(), 1, s_SelectedLanguage, s_ScrollValue);