This commit is contained in:
KebsCS 2024-09-14 18:24:59 +02:00 committed by GitHub
commit bff75f1280
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 123 additions and 55 deletions

View file

@ -490,7 +490,7 @@ MACRO_CONFIG_INT(SvSpecFrequency, sv_pause_frequency, 1, 0, 9999, CFGFLAG_SERVER
MACRO_CONFIG_INT(SvInvite, sv_invite, 1, 0, 1, CFGFLAG_SERVER, "Whether players can invite other players to teams") MACRO_CONFIG_INT(SvInvite, sv_invite, 1, 0, 1, CFGFLAG_SERVER, "Whether players can invite other players to teams")
MACRO_CONFIG_INT(SvInviteFrequency, sv_invite_frequency, 1, 0, 9999, CFGFLAG_SERVER, "The minimum allowed delay between invites") MACRO_CONFIG_INT(SvInviteFrequency, sv_invite_frequency, 1, 0, 9999, CFGFLAG_SERVER, "The minimum allowed delay between invites")
MACRO_CONFIG_INT(SvTeleOthersAuthLevel, sv_tele_others_auth_level, 1, 1, 3, CFGFLAG_SERVER, "The auth level you need to tele others") MACRO_CONFIG_INT(SvTeleOthersAuthLevel, sv_tele_others_auth_level, 1, 1, 3, CFGFLAG_SERVER, "The auth level you need to tele others")
MACRO_CONFIG_INT(SvRegionalRankings, sv_regional_rankings, 1, 0, 1, CFGFLAG_SERVER, "Display regional rankings in /rank and /top5") MACRO_CONFIG_INT(SvRegionalRankings, sv_regional_rankings, 1, 0, 1, CFGFLAG_SERVER, "Display regional rankings in /rank, /top5 and /top5team")
MACRO_CONFIG_INT(SvEmotionalTees, sv_emotional_tees, 1, -1, 1, CFGFLAG_SERVER, "Whether eye change of tees is enabled with emoticons = 1, not = 0, -1 not at all") MACRO_CONFIG_INT(SvEmotionalTees, sv_emotional_tees, 1, -1, 1, CFGFLAG_SERVER, "Whether eye change of tees is enabled with emoticons = 1, not = 0, -1 not at all")
MACRO_CONFIG_INT(SvEmoticonMsDelay, sv_emoticon_ms_delay, 3000, 20, 999999999, CFGFLAG_SERVER, "The time in ms a player has to wait before allowing the next over-head emoticons") MACRO_CONFIG_INT(SvEmoticonMsDelay, sv_emoticon_ms_delay, 3000, 20, 999999999, CFGFLAG_SERVER, "The time in ms a player has to wait before allowing the next over-head emoticons")

View file

@ -99,6 +99,48 @@ bool CTeamrank::SamePlayers(const std::vector<std::string> *pvSortedNames)
return true; return true;
} }
bool CTeamrank::GetSqlTop5Team(IDbConnection *pSqlServer, bool *pEnd, char *pError, int ErrorSize, char (*paMessages)[512], int *Line, int Count)
{
char aTime[32];
int StartLine = *Line;
for(*Line = StartLine; *Line < StartLine + Count; (*Line)++)
{
bool Last = false;
float Time = pSqlServer->GetFloat(2);
str_time_float(Time, TIME_HOURS_CENTISECS, aTime, sizeof(aTime));
int Rank = pSqlServer->GetInt(3);
int TeamSize = pSqlServer->GetInt(4);
char aNames[2300] = {0};
for(int i = 0; i < TeamSize; i++)
{
char aName[MAX_NAME_LENGTH];
pSqlServer->GetString(1, aName, sizeof(aName));
str_append(aNames, aName);
if(i < TeamSize - 2)
str_append(aNames, ", ");
else if(i == TeamSize - 2)
str_append(aNames, " & ");
if(pSqlServer->Step(&Last, pError, ErrorSize))
{
return true;
}
if(Last)
{
break;
}
}
str_format(paMessages[*Line], sizeof(paMessages[*Line]), "%d. %s Team Time: %s",
Rank, aNames, aTime);
if(Last)
{
(*Line)++;
break;
}
}
return false;
}
bool CScoreWorker::LoadBestTime(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize) bool CScoreWorker::LoadBestTime(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize)
{ {
const auto *pData = dynamic_cast<const CSqlLoadBestTimeData *>(pGameData); const auto *pData = dynamic_cast<const CSqlLoadBestTimeData *>(pGameData);
@ -1071,34 +1113,40 @@ bool CScoreWorker::ShowTeamTop5(IDbConnection *pSqlServer, const ISqlData *pGame
int LimitStart = maximum(absolute(pData->m_Offset) - 1, 0); int LimitStart = maximum(absolute(pData->m_Offset) - 1, 0);
const char *pOrder = pData->m_Offset >= 0 ? "ASC" : "DESC"; const char *pOrder = pData->m_Offset >= 0 ? "ASC" : "DESC";
const char *pAny = "%";
// check sort method // check sort method
char aBuf[1024]; char aBuf[1024];
str_format(aBuf, sizeof(aBuf), str_format(aBuf, sizeof(aBuf),
"SELECT Name, Time, Ranking, TeamSize " "SELECT Name, Time, Ranking, TeamSize "
"FROM (" // limit to 5 "FROM ("
" SELECT TeamSize, Ranking, Id " " SELECT TeamSize, Ranking, Id, Server "
" FROM (" // teamrank score board " FROM (" // teamrank score board
" SELECT RANK() OVER w AS Ranking, COUNT(*) AS Teamsize, Id " " SELECT RANK() OVER w AS Ranking, COUNT(*) AS Teamsize, Id, Server "
" FROM %s_teamrace " " FROM ("
" SELECT * FROM %s_teamrace as tr "
" INNER JOIN %s_race as rr ON tr.Map = rr.Map AND tr.Name = rr.Name AND tr.Time = rr.Time AND tr.Timestamp = rr.Timestamp"
" ) "
" WHERE Map = ? " " WHERE Map = ? "
" GROUP BY ID " " GROUP BY ID "
" WINDOW w AS (ORDER BY Min(Time))" " WINDOW w AS (ORDER BY Min(Time))"
" ) as l1 " " ) as l1 "
" WHERE Server LIKE ? "
" ORDER BY Ranking %s " " ORDER BY Ranking %s "
" LIMIT %d, 5" " LIMIT %d, ?"
") as l2 " ") as l2 "
"INNER JOIN %s_teamrace as r ON l2.Id = r.Id " "INNER JOIN %s_teamrace as r ON l2.Id = r.Id "
"ORDER BY Ranking %s, r.Id, Name ASC", "ORDER BY Ranking %s, r.Id, Name ASC",
pSqlServer->GetPrefix(), pOrder, LimitStart, pSqlServer->GetPrefix(), pOrder); pSqlServer->GetPrefix(), pSqlServer->GetPrefix(), pOrder, LimitStart, pSqlServer->GetPrefix(), pOrder);
if(pSqlServer->PrepareStatement(aBuf, pError, ErrorSize)) if(pSqlServer->PrepareStatement(aBuf, pError, ErrorSize))
{ {
return true; return true;
} }
pSqlServer->BindString(1, pData->m_aMap); pSqlServer->BindString(1, pData->m_aMap);
pSqlServer->BindString(2, pAny);
pSqlServer->BindInt(3, 5);
// show teamtop5
int Line = 0; int Line = 0;
str_copy(paMessages[Line++], "------- Team Top 5 -------", sizeof(paMessages[Line])); str_copy(paMessages[Line++], "------- Team Top 5 -------", sizeof(paMessages[Line]));
@ -1109,44 +1157,45 @@ bool CScoreWorker::ShowTeamTop5(IDbConnection *pSqlServer, const ISqlData *pGame
} }
if(!End) if(!End)
{ {
for(Line = 1; Line < 6; Line++) // print if(CTeamrank::GetSqlTop5Team(pSqlServer, &End, pError, ErrorSize, paMessages, &Line, 5))
{ {
bool Last = false; return true;
float Time = pSqlServer->GetFloat(2); }
str_time_float(Time, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf)); }
int Rank = pSqlServer->GetInt(3);
int TeamSize = pSqlServer->GetInt(4); if(!g_Config.m_SvRegionalRankings)
{
char aNames[2300] = {0}; str_copy(paMessages[Line], "-------------------------------", sizeof(paMessages[Line]));
for(int i = 0; i < TeamSize; i++) return false;
{ }
char aName[MAX_NAME_LENGTH];
pSqlServer->GetString(1, aName, sizeof(aName)); char aServerLike[16];
str_append(aNames, aName); str_format(aServerLike, sizeof(aServerLike), "%%%s%%", pData->m_aServer);
if(i < TeamSize - 2)
str_append(aNames, ", "); if(pSqlServer->PrepareStatement(aBuf, pError, ErrorSize))
else if(i == TeamSize - 2) {
str_append(aNames, " & "); return true;
if(pSqlServer->Step(&Last, pError, ErrorSize)) }
{ pSqlServer->BindString(1, pData->m_aMap);
return true; pSqlServer->BindString(2, aServerLike);
} pSqlServer->BindInt(3, 3);
if(Last)
{ str_format(pResult->m_Data.m_aaMessages[Line], sizeof(pResult->m_Data.m_aaMessages[Line]),
break; "----- %s Team Top -----", pData->m_aServer);
} Line++;
}
str_format(paMessages[Line], sizeof(paMessages[Line]), "%d. %s Team Time: %s", if(pSqlServer->Step(&End, pError, ErrorSize))
Rank, aNames, aBuf); {
if(Last) return true;
{ }
Line++; if(!End)
break; {
} if(CTeamrank::GetSqlTop5Team(pSqlServer, &End, pError, ErrorSize, paMessages, &Line, 3))
{
return true;
} }
} }
str_copy(paMessages[Line], "-------------------------------", sizeof(paMessages[Line]));
return false; return false;
} }

View file

@ -281,6 +281,8 @@ struct CTeamrank
bool NextSqlResult(IDbConnection *pSqlServer, bool *pEnd, char *pError, int ErrorSize); bool NextSqlResult(IDbConnection *pSqlServer, bool *pEnd, char *pError, int ErrorSize);
bool SamePlayers(const std::vector<std::string> *pvSortedNames); bool SamePlayers(const std::vector<std::string> *pvSortedNames);
static bool GetSqlTop5Team(IDbConnection *pSqlServer, bool *pEnd, char *pError, int ErrorSize, char (*paMessages)[512], int *StartLine, int Count);
}; };
struct CScoreWorker struct CScoreWorker

View file

@ -282,41 +282,46 @@ struct TeamScore : public Score
{ {
void SetUp() override void SetUp() override
{ {
CSqlTeamScoreData teamScoreData; InsertTeamRank(100.0);
str_copy(teamScoreData.m_aMap, "Kobra 3", sizeof(teamScoreData.m_aMap));
str_copy(teamScoreData.m_aGameUuid, "8d300ecf-5873-4297-bee5-95668fdff320", sizeof(teamScoreData.m_aGameUuid));
teamScoreData.m_Size = 2;
str_copy(teamScoreData.m_aaNames[0], "nameless tee", sizeof(teamScoreData.m_aaNames[0]));
str_copy(teamScoreData.m_aaNames[1], "brainless tee", sizeof(teamScoreData.m_aaNames[1]));
teamScoreData.m_Time = 100.0;
str_copy(teamScoreData.m_aTimestamp, "2021-11-24 19:24:08", sizeof(teamScoreData.m_aTimestamp));
ASSERT_FALSE(CScoreWorker::SaveTeamScore(m_pConn, &teamScoreData, Write::NORMAL, m_aError, sizeof(m_aError))) << m_aError;
str_copy(m_PlayerRequest.m_aMap, "Kobra 3", sizeof(m_PlayerRequest.m_aMap));
str_copy(m_PlayerRequest.m_aRequestingPlayer, "brainless tee", sizeof(m_PlayerRequest.m_aRequestingPlayer));
m_PlayerRequest.m_Offset = 0;
} }
void InsertTeamRank(float Time = 100.0) void InsertTeamRank(float Time = 100.0)
{ {
str_copy(g_Config.m_SvSqlServerName, "USA", sizeof(g_Config.m_SvSqlServerName));
CSqlTeamScoreData teamScoreData; CSqlTeamScoreData teamScoreData;
CSqlScoreData ScoreData(std::make_shared<CScorePlayerResult>());
str_copy(teamScoreData.m_aMap, "Kobra 3", sizeof(teamScoreData.m_aMap)); str_copy(teamScoreData.m_aMap, "Kobra 3", sizeof(teamScoreData.m_aMap));
str_copy(ScoreData.m_aMap, "Kobra 3", sizeof(ScoreData.m_aMap));
str_copy(teamScoreData.m_aGameUuid, "8d300ecf-5873-4297-bee5-95668fdff320", sizeof(teamScoreData.m_aGameUuid)); str_copy(teamScoreData.m_aGameUuid, "8d300ecf-5873-4297-bee5-95668fdff320", sizeof(teamScoreData.m_aGameUuid));
str_copy(ScoreData.m_aGameUuid, "8d300ecf-5873-4297-bee5-95668fdff320", sizeof(ScoreData.m_aGameUuid));
teamScoreData.m_Size = 2; teamScoreData.m_Size = 2;
str_copy(teamScoreData.m_aaNames[0], "nameless tee", sizeof(teamScoreData.m_aaNames[0])); str_copy(teamScoreData.m_aaNames[0], "nameless tee", sizeof(teamScoreData.m_aaNames[0]));
str_copy(teamScoreData.m_aaNames[1], "brainless tee", sizeof(teamScoreData.m_aaNames[1])); str_copy(teamScoreData.m_aaNames[1], "brainless tee", sizeof(teamScoreData.m_aaNames[1]));
teamScoreData.m_Time = Time; teamScoreData.m_Time = Time;
ScoreData.m_Time = Time;
str_copy(teamScoreData.m_aTimestamp, "2021-11-24 19:24:08", sizeof(teamScoreData.m_aTimestamp)); str_copy(teamScoreData.m_aTimestamp, "2021-11-24 19:24:08", sizeof(teamScoreData.m_aTimestamp));
str_copy(ScoreData.m_aTimestamp, "2021-11-24 19:24:08", sizeof(ScoreData.m_aTimestamp));
for(int i = 0; i < NUM_CHECKPOINTS; i++)
ScoreData.m_aCurrentTimeCp[i] = 0;
ASSERT_FALSE(CScoreWorker::SaveTeamScore(m_pConn, &teamScoreData, Write::NORMAL, m_aError, sizeof(m_aError))) << m_aError; ASSERT_FALSE(CScoreWorker::SaveTeamScore(m_pConn, &teamScoreData, Write::NORMAL, m_aError, sizeof(m_aError))) << m_aError;
str_copy(m_PlayerRequest.m_aMap, "Kobra 3", sizeof(m_PlayerRequest.m_aMap)); str_copy(m_PlayerRequest.m_aMap, "Kobra 3", sizeof(m_PlayerRequest.m_aMap));
str_copy(m_PlayerRequest.m_aRequestingPlayer, "brainless tee", sizeof(m_PlayerRequest.m_aRequestingPlayer)); str_copy(m_PlayerRequest.m_aRequestingPlayer, "brainless tee", sizeof(m_PlayerRequest.m_aRequestingPlayer));
str_copy(ScoreData.m_aRequestingPlayer, "brainless tee", sizeof(ScoreData.m_aRequestingPlayer));
str_copy(ScoreData.m_aName, "nameless tee", sizeof(ScoreData.m_aName));
ScoreData.m_ClientId = 0;
ASSERT_FALSE(CScoreWorker::SaveScore(m_pConn, &ScoreData, Write::NORMAL, m_aError, sizeof(m_aError))) << m_aError;
str_copy(ScoreData.m_aName, "brainless tee", sizeof(ScoreData.m_aName));
ScoreData.m_ClientId = 1;
ASSERT_FALSE(CScoreWorker::SaveScore(m_pConn, &ScoreData, Write::NORMAL, m_aError, sizeof(m_aError))) << m_aError;
m_PlayerRequest.m_Offset = 0; m_PlayerRequest.m_Offset = 0;
} }
}; };
TEST_P(TeamScore, All) TEST_P(TeamScore, All)
{ {
g_Config.m_SvRegionalRankings = false;
ASSERT_FALSE(CScoreWorker::ShowTeamTop5(m_pConn, &m_PlayerRequest, m_aError, sizeof(m_aError))) << m_aError; ASSERT_FALSE(CScoreWorker::ShowTeamTop5(m_pConn, &m_PlayerRequest, m_aError, sizeof(m_aError))) << m_aError;
ExpectLines(m_pPlayerResult, ExpectLines(m_pPlayerResult,
{"------- Team Top 5 -------", {"------- Team Top 5 -------",
@ -324,6 +329,18 @@ TEST_P(TeamScore, All)
"-------------------------------"}); "-------------------------------"});
} }
TEST_P(TeamScore, TeamTop5Regional)
{
g_Config.m_SvRegionalRankings = true;
str_copy(m_PlayerRequest.m_aServer, "USA", sizeof(m_PlayerRequest.m_aServer));
ASSERT_FALSE(CScoreWorker::ShowTeamTop5(m_pConn, &m_PlayerRequest, m_aError, sizeof(m_aError))) << m_aError;
ExpectLines(m_pPlayerResult,
{"------- Team Top 5 -------",
"1. brainless tee & nameless tee Team Time: 01:40.00",
"----- USA Team Top -----",
"1. brainless tee & nameless tee Team Time: 01:40.00"});
}
TEST_P(TeamScore, PlayerExists) TEST_P(TeamScore, PlayerExists)
{ {
str_copy(m_PlayerRequest.m_aName, "brainless tee", sizeof(m_PlayerRequest.m_aName)); str_copy(m_PlayerRequest.m_aName, "brainless tee", sizeof(m_PlayerRequest.m_aName));