mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge #3504
3504: Display median time instead of average (fixes #3399) r=heinrich5991 a=def- Do we want average too or just median? ## Checklist - [x] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [x] Tested in combination with possibly related configuration options - [ ] Written a unit test if it works standalone, system.c especially - [x] Considered possible null pointers and out of bounds array indexing - [x] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: def <dennis@felsin9.de>
This commit is contained in:
commit
174eeab80d
|
@ -21,7 +21,7 @@ public:
|
|||
virtual IDbConnection *Copy() = 0;
|
||||
|
||||
// returns the database prefix
|
||||
const char *GetPrefix() { return m_aPrefix; }
|
||||
const char *GetPrefix() const { return m_aPrefix; }
|
||||
virtual const char *BinaryCollate() const = 0;
|
||||
// can be inserted into queries to convert a timestamp variable to the unix timestamp
|
||||
virtual void ToUnixTimestamp(const char *pTimestamp, char *aBuf, unsigned int BufferSize) = 0;
|
||||
|
@ -35,6 +35,8 @@ public:
|
|||
virtual const char *InsertIgnore() const = 0;
|
||||
// ORDER BY RANDOM()/RAND()
|
||||
virtual const char *Random() const = 0;
|
||||
// Get Median Map Time from l.Map
|
||||
virtual const char *MedianMapTime(char *pBuffer, int BufferSize) const = 0;
|
||||
|
||||
enum Status
|
||||
{
|
||||
|
|
|
@ -309,6 +309,18 @@ int CMysqlConnection::GetBlob(int Col, unsigned char *pBuffer, int BufferSize) c
|
|||
#endif
|
||||
}
|
||||
|
||||
const char *CMysqlConnection::MedianMapTime(char *pBuffer, int BufferSize) const
|
||||
{
|
||||
str_format(pBuffer, BufferSize,
|
||||
"SELECT MEDIAN(Time) "
|
||||
"OVER (PARTITION BY Map) "
|
||||
"FROM %s_race "
|
||||
"GROUP BY Map "
|
||||
"HAVING Map = l.Map",
|
||||
GetPrefix());
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
void CMysqlConnection::AddPoints(const char *pPlayer, int Points)
|
||||
{
|
||||
char aBuf[512];
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
virtual const char *CollateNocase() const { return "CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci"; }
|
||||
virtual const char *InsertIgnore() const { return "INSERT IGNORE"; };
|
||||
virtual const char *Random() const { return "RAND()"; };
|
||||
virtual const char *MedianMapTime(char *pBuffer, int BufferSize) const;
|
||||
|
||||
virtual Status Connect();
|
||||
virtual void Disconnect();
|
||||
|
|
|
@ -218,6 +218,23 @@ int CSqliteConnection::GetBlob(int Col, unsigned char *pBuffer, int BufferSize)
|
|||
return Size;
|
||||
}
|
||||
|
||||
const char *CSqliteConnection::MedianMapTime(char *pBuffer, int BufferSize) const
|
||||
{
|
||||
str_format(pBuffer, BufferSize,
|
||||
"SELECT AVG("
|
||||
" CASE counter %% 2 "
|
||||
" WHEN 0 THEN CASE WHEN rn IN (counter / 2, counter / 2 + 1) THEN Time END "
|
||||
" WHEN 1 THEN CASE WHEN rn = counter / 2 + 1 THEN Time END END) "
|
||||
" OVER (PARTITION BY Map) AS Median "
|
||||
"FROM ("
|
||||
" SELECT *, ROW_NUMBER() "
|
||||
" OVER (PARTITION BY Map ORDER BY Time) rn, COUNT(*) "
|
||||
" OVER (PARTITION BY Map) counter "
|
||||
" FROM %s_race where Map = l.Map) as r",
|
||||
GetPrefix());
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
bool CSqliteConnection::Execute(const char *pQuery)
|
||||
{
|
||||
char *pErrorMsg;
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
virtual const char *CollateNocase() const { return "? COLLATE NOCASE"; }
|
||||
virtual const char *InsertIgnore() const { return "INSERT OR IGNORE"; };
|
||||
virtual const char *Random() const { return "RANDOM()"; };
|
||||
virtual const char *MedianMapTime(char *pBuffer, int BufferSize) const;
|
||||
|
||||
virtual Status Connect();
|
||||
virtual void Disconnect();
|
||||
|
|
|
@ -355,12 +355,13 @@ bool CScore::MapInfoThread(IDbConnection *pSqlServer, const ISqlData *pGameData)
|
|||
char aTimestamp[512];
|
||||
pSqlServer->ToUnixTimestamp("l.Timestamp", aTimestamp, sizeof(aTimestamp));
|
||||
|
||||
char aBuf[1024];
|
||||
char aMedianMapTime[2048];
|
||||
char aBuf[4096];
|
||||
str_format(aBuf, sizeof(aBuf),
|
||||
"SELECT l.Map, l.Server, Mapper, Points, Stars, "
|
||||
" (SELECT COUNT(Name) FROM %s_race WHERE Map = l.Map) AS Finishes, "
|
||||
" (SELECT COUNT(DISTINCT Name) FROM %s_race WHERE Map = l.Map) AS Finishers, "
|
||||
" (SELECT ROUND(AVG(Time)) FROM %s_race WHERE Map = l.Map) AS Average, "
|
||||
" (%s) AS Median, "
|
||||
" %s AS Stamp, "
|
||||
" %s-%s AS Ago, "
|
||||
" (SELECT MIN(Time) FROM %s_race WHERE Map = l.Map AND Name = ?) AS OwnTime "
|
||||
|
@ -374,7 +375,8 @@ bool CScore::MapInfoThread(IDbConnection *pSqlServer, const ISqlData *pGameData)
|
|||
" Map "
|
||||
" LIMIT 1"
|
||||
") as l;",
|
||||
pSqlServer->GetPrefix(), pSqlServer->GetPrefix(), pSqlServer->GetPrefix(),
|
||||
pSqlServer->GetPrefix(), pSqlServer->GetPrefix(),
|
||||
pSqlServer->MedianMapTime(aMedianMapTime, sizeof(aMedianMapTime)),
|
||||
aTimestamp, aCurrentTimestamp, aTimestamp,
|
||||
pSqlServer->GetPrefix(), pSqlServer->GetPrefix(),
|
||||
pSqlServer->CollateNocase());
|
||||
|
@ -396,7 +398,7 @@ bool CScore::MapInfoThread(IDbConnection *pSqlServer, const ISqlData *pGameData)
|
|||
int Stars = pSqlServer->GetInt(5);
|
||||
int Finishes = pSqlServer->GetInt(6);
|
||||
int Finishers = pSqlServer->GetInt(7);
|
||||
int Average = pSqlServer->GetInt(8);
|
||||
float Median = pSqlServer->GetInt(8);
|
||||
int Stamp = pSqlServer->GetInt(9);
|
||||
int Ago = pSqlServer->GetInt(10);
|
||||
float OwnTime = pSqlServer->GetFloat(11);
|
||||
|
@ -409,11 +411,11 @@ bool CScore::MapInfoThread(IDbConnection *pSqlServer, const ISqlData *pGameData)
|
|||
str_format(aReleasedString, sizeof(aReleasedString), ", released %s ago", aAgoString);
|
||||
}
|
||||
|
||||
char aAverageString[60] = "\0";
|
||||
if(Average > 0)
|
||||
char aMedianString[60] = "\0";
|
||||
if(Median > 0)
|
||||
{
|
||||
str_time((int64)Average * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
||||
str_format(aAverageString, sizeof(aAverageString), " in %s average", aBuf);
|
||||
str_time((int64)Median * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
||||
str_format(aMedianString, sizeof(aMedianString), " in %s median", aBuf);
|
||||
}
|
||||
|
||||
char aStars[20];
|
||||
|
@ -443,7 +445,7 @@ bool CScore::MapInfoThread(IDbConnection *pSqlServer, const ISqlData *pGameData)
|
|||
aReleasedString,
|
||||
Finishes, Finishes == 1 ? "finish" : "finishes",
|
||||
Finishers, Finishers == 1 ? "tee" : "tees",
|
||||
aAverageString, aOwnFinishesString);
|
||||
aMedianString, aOwnFinishesString);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue