mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Added server sided automatic demo recording
This commit is contained in:
parent
0f11cf014c
commit
e2664c1b00
|
@ -32,6 +32,7 @@
|
|||
#include <engine/shared/protocol.h>
|
||||
#include <engine/shared/ringbuffer.h>
|
||||
#include <engine/shared/snapshot.h>
|
||||
#include <engine/shared/filecollection.h>
|
||||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
#include <versionsrv/versionsrv.h>
|
||||
|
@ -231,185 +232,6 @@ 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<int>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser)
|
||||
{
|
||||
CFileCollection *pThis = static_cast<CFileCollection *>(pUser);
|
||||
|
||||
// check for valid file name format
|
||||
if(IsDir || !pThis->IsFilenameValid(pFilename))
|
||||
return 0;
|
||||
|
||||
// extract the timestamp
|
||||
int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1);
|
||||
|
||||
// add the entry
|
||||
pThis->AddEntry(Timestamp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotDelta)
|
||||
{
|
||||
m_pEditor = 0;
|
||||
|
|
|
@ -51,36 +51,6 @@ 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 int FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser);
|
||||
};
|
||||
|
||||
|
||||
class CClient : public IClient, public CDemoPlayer::IListner
|
||||
{
|
||||
// needed interfaces
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
|
||||
virtual bool IsAuthed(int ClientID) = 0;
|
||||
virtual void Kick(int ClientID, const char *pReason) = 0;
|
||||
|
||||
virtual void DemoRecorder_HandleAutoStart() = 0;
|
||||
};
|
||||
|
||||
class IGameServer : public IInterface
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <engine/shared/packer.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
#include <engine/shared/snapshot.h>
|
||||
#include <engine/shared/filecollection.h>
|
||||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
|
||||
|
@ -1519,6 +1520,25 @@ void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser)
|
|||
((CServer *)pUser)->m_RunServer = 0;
|
||||
}
|
||||
|
||||
void CServer::DemoRecorder_HandleAutoStart()
|
||||
{
|
||||
if(g_Config.m_SvAutoDemoRecord)
|
||||
{
|
||||
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(Storage(), m_pConsole, aFilename, GameServer()->NetVersion(), m_aCurrentMap, m_CurrentMapCrc, "server");
|
||||
if(g_Config.m_SvAutoDemoMax)
|
||||
{
|
||||
// clean up auto recorded demos
|
||||
CFileCollection AutoDemos;
|
||||
AutoDemos.Init(Storage(), "demos/server", "autorecord", ".demo", g_Config.m_SvAutoDemoMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::ConRecord(IConsole::IResult *pResult, void *pUser)
|
||||
{
|
||||
CServer* pServer = (CServer *)pUser;
|
||||
|
|
|
@ -148,6 +148,8 @@ public:
|
|||
|
||||
void Kick(int ClientID, const char *pReason);
|
||||
|
||||
void DemoRecorder_HandleAutoStart();
|
||||
|
||||
//int Tick()
|
||||
int64 TickStartTime(int Tick);
|
||||
//int TickSpeed()
|
||||
|
|
|
@ -86,6 +86,8 @@ MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remo
|
|||
MACRO_CONFIG_STR(SvRconModPassword, sv_rcon_mod_password, 32, "", CFGFLAG_SERVER, "Remote console password for moderators (limited access)")
|
||||
MACRO_CONFIG_INT(SvRconMaxTries, sv_rcon_max_tries, 3, 0, 100, CFGFLAG_SERVER, "Maximum number of tries for remote console authentication")
|
||||
MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if remote console authentication fails. 0 makes it just use kick")
|
||||
MACRO_CONFIG_INT(SvAutoDemoRecord, sv_auto_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos")
|
||||
MACRO_CONFIG_INT(SvAutoDemoMax, sv_auto_demo_max, 10, 0, 1000, CFGFLAG_SERVER, "Maximum number of automatically recorded demos (0 = no limit)")
|
||||
|
||||
MACRO_CONFIG_STR(EcBindaddr, ec_bindaddr, 128, "localhost", CFGFLAG_SERVER, "Address to bind the external console to. Anything but 'localhost' is dangerous")
|
||||
MACRO_CONFIG_INT(EcPort, ec_port, 0, 0, 0, CFGFLAG_SERVER, "Port to use for the external console")
|
||||
|
|
186
src/engine/shared/filecollection.cpp
Normal file
186
src/engine/shared/filecollection.cpp
Normal file
|
@ -0,0 +1,186 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
|
||||
#include <base/math.h>
|
||||
|
||||
#include <engine/storage.h>
|
||||
|
||||
#include "filecollection.h"
|
||||
|
||||
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<int>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser)
|
||||
{
|
||||
CFileCollection *pThis = static_cast<CFileCollection *>(pUser);
|
||||
|
||||
// check for valid file name format
|
||||
if(IsDir || !pThis->IsFilenameValid(pFilename))
|
||||
return 0;
|
||||
|
||||
// extract the timestamp
|
||||
int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1);
|
||||
|
||||
// add the entry
|
||||
pThis->AddEntry(Timestamp);
|
||||
|
||||
return 0;
|
||||
}
|
35
src/engine/shared/filecollection.h
Normal file
35
src/engine/shared/filecollection.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
||||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
#ifndef ENGINE_SHARED_FILECOLLECTION_H
|
||||
#define ENGINE_SHARED_FILECOLLECTION_H
|
||||
|
||||
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 int FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -217,6 +217,7 @@ void IGameController::StartRound()
|
|||
m_aTeamscore[TEAM_RED] = 0;
|
||||
m_aTeamscore[TEAM_BLUE] = 0;
|
||||
m_ForceBalanced = false;
|
||||
Server()->DemoRecorder_HandleAutoStart();
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS);
|
||||
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
||||
|
|
Loading…
Reference in a new issue