mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #3392
3392: Add /top5team s?i command to show all team ranks of a player r=def- a=Zwelf I like to see whom I have finished a map with. `/teamrank` only provides one result. With this command I can request all teams I finished a map with. ## Checklist - [x] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test if it works standalone, system.c especially - [ ] 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: Zwelf <zwelf@strct.cc>
This commit is contained in:
commit
13762aa197
|
@ -387,10 +387,37 @@ void CGameContext::ConTeamTop5(IConsole::IResult *pResult, void *pUserData)
|
|||
return;
|
||||
}
|
||||
|
||||
if(pResult->NumArguments() > 0)
|
||||
pSelf->Score()->ShowTeamTop5(pResult->m_ClientID, pResult->GetInteger(0));
|
||||
if(pResult->NumArguments() == 0)
|
||||
{
|
||||
pSelf->Score()->ShowTeamTop5(pResult->m_ClientID, 1);
|
||||
}
|
||||
else if(pResult->NumArguments() == 1)
|
||||
{
|
||||
if(pResult->GetInteger(0) != 0)
|
||||
{
|
||||
pSelf->Score()->ShowTeamTop5(pResult->m_ClientID, pResult->GetInteger(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *pRequestedName = (str_comp(pResult->GetString(0), "me") == 0) ?
|
||||
pSelf->Server()->ClientName(pResult->m_ClientID) :
|
||||
pResult->GetString(0);
|
||||
pSelf->Score()->ShowTeamTop5(pResult->m_ClientID, pRequestedName, 0);
|
||||
}
|
||||
}
|
||||
else if(pResult->NumArguments() == 2 && pResult->GetInteger(1) != 0)
|
||||
{
|
||||
const char *pRequestedName = (str_comp(pResult->GetString(0), "me") == 0) ?
|
||||
pSelf->Server()->ClientName(pResult->m_ClientID) :
|
||||
pResult->GetString(0);
|
||||
pSelf->Score()->ShowTeamTop5(pResult->m_ClientID, pRequestedName, pResult->GetInteger(1));
|
||||
}
|
||||
else
|
||||
pSelf->Score()->ShowTeamTop5(pResult->m_ClientID);
|
||||
{
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "teamtop5", "/top5team needs 0, 1 or 2 parameter. 1. = name, 2. = start number");
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "teamtop5", "Example: /top5team, /top5team me, /top5team Hans, /top5team \"Papa Smurf\" 5");
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "teamtop5", "Bad: /top5team Papa Smurf 5 # Good: /top5team \"Papa Smurf\" 5 ");
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConTop5(IConsole::IResult *pResult, void *pUserData)
|
||||
|
|
|
@ -33,8 +33,8 @@ CHAT_COMMAND("map", "?r[map]", CFGFLAG_CHAT | CFGFLAG_SERVER | CFGFLAG_NONTEEHIS
|
|||
CHAT_COMMAND("rankteam", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamRank, this, "Shows the team rank of player with name r (your team rank by default)")
|
||||
CHAT_COMMAND("teamrank", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamRank, this, "Shows the team rank of player with name r (your team rank by default)")
|
||||
CHAT_COMMAND("rank", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)")
|
||||
CHAT_COMMAND("top5team", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default, -1 for worst)")
|
||||
CHAT_COMMAND("teamtop5", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default, -1 for worst)")
|
||||
CHAT_COMMAND("top5team", "?s[player name] ?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder or of a player beginning with rank i (1 by default, -1 for worst)")
|
||||
CHAT_COMMAND("teamtop5", "?s[player name] ?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder or of a player beginning with rank i (1 by default, -1 for worst)")
|
||||
CHAT_COMMAND("top5", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTop5, this, "Shows five ranks of the ladder beginning with rank i (1 by default, -1 for worst)")
|
||||
CHAT_COMMAND("times", "?s[player name] ?i[number of times to skip]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTimes, this, "/times ?s?i shows last 5 times of the server or of a player beginning with name s starting with time i (i = 1 by default, -1 for first)")
|
||||
CHAT_COMMAND("points", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConPoints, this, "Shows the global points of a player beginning with name r (your rank by default)")
|
||||
|
|
|
@ -918,6 +918,93 @@ bool CScore::ShowTeamTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGame
|
|||
return true;
|
||||
}
|
||||
|
||||
void CScore::ShowTeamTop5(int ClientID, const char *pName, int Offset)
|
||||
{
|
||||
if(RateLimitPlayer(ClientID))
|
||||
return;
|
||||
ExecPlayerThread(ShowPlayerTeamTop5Thread, "show team top5 player", ClientID, pName, Offset);
|
||||
}
|
||||
|
||||
bool CScore::ShowPlayerTeamTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGameData)
|
||||
{
|
||||
const CSqlPlayerRequest *pData = dynamic_cast<const CSqlPlayerRequest *>(pGameData);
|
||||
CScorePlayerResult *pResult = dynamic_cast<CScorePlayerResult *>(pGameData->m_pResult.get());
|
||||
auto *paMessages = pResult->m_Data.m_aaMessages;
|
||||
|
||||
int LimitStart = maximum(abs(pData->m_Offset) - 1, 0);
|
||||
const char *pOrder = pData->m_Offset >= 0 ? "ASC" : "DESC";
|
||||
|
||||
// check sort method
|
||||
char aBuf[2400];
|
||||
|
||||
str_format(aBuf, sizeof(aBuf),
|
||||
"SELECT l.ID, Name, Time, Rank "
|
||||
"FROM (" // teamrank score board
|
||||
" SELECT RANK() OVER w AS Rank, ID "
|
||||
" FROM %s_teamrace "
|
||||
" WHERE Map = ? "
|
||||
" GROUP BY ID "
|
||||
" WINDOW w AS (ORDER BY Time)"
|
||||
") AS TeamRank INNER JOIN (" // select rank with Name in team
|
||||
" SELECT ID "
|
||||
" FROM %s_teamrace "
|
||||
" WHERE Map = ? AND Name = ? "
|
||||
" ORDER BY Time %s "
|
||||
" LIMIT %d, 5 "
|
||||
") AS l ON TeamRank.ID = l.ID "
|
||||
"INNER JOIN %s_teamrace AS r ON l.ID = r.ID "
|
||||
"ORDER BY Time %s, l.ID ",
|
||||
pSqlServer->GetPrefix(), pSqlServer->GetPrefix(), pOrder, LimitStart, pSqlServer->GetPrefix(), pOrder);
|
||||
pSqlServer->PrepareStatement(aBuf);
|
||||
pSqlServer->BindString(1, pData->m_Map);
|
||||
pSqlServer->BindString(2, pData->m_Map);
|
||||
pSqlServer->BindString(3, pData->m_Name);
|
||||
|
||||
if(pSqlServer->Step())
|
||||
{
|
||||
// show teamtop5
|
||||
int Line = 0;
|
||||
str_copy(paMessages[Line++], "------- Team Top 5 -------", sizeof(paMessages[Line]));
|
||||
|
||||
for(Line = 1; Line < 6; Line++) // print
|
||||
{
|
||||
float Time = pSqlServer->GetFloat(3);
|
||||
str_time_float(Time, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf));
|
||||
int Rank = pSqlServer->GetInt(4);
|
||||
CTeamrank Teamrank;
|
||||
bool Last = !Teamrank.NextSqlResult(pSqlServer);
|
||||
|
||||
char aFormattedNames[512] = "";
|
||||
for(unsigned int Name = 0; Name < Teamrank.m_NumNames; Name++)
|
||||
{
|
||||
str_append(aFormattedNames, Teamrank.m_aaNames[Name], sizeof(aFormattedNames));
|
||||
|
||||
if(Name < Teamrank.m_NumNames - 2)
|
||||
str_append(aFormattedNames, ", ", sizeof(aFormattedNames));
|
||||
else if(Name < Teamrank.m_NumNames - 1)
|
||||
str_append(aFormattedNames, " & ", sizeof(aFormattedNames));
|
||||
}
|
||||
|
||||
str_format(paMessages[Line], sizeof(paMessages[Line]), "%d. %s Team Time: %s",
|
||||
Rank, aFormattedNames, aBuf);
|
||||
if(Last)
|
||||
{
|
||||
Line++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
str_copy(paMessages[Line], "-------------------------------", sizeof(paMessages[Line]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pData->m_Offset == 0)
|
||||
str_format(paMessages[0], sizeof(paMessages[0]), "%s has no team ranks", pData->m_Name);
|
||||
else
|
||||
str_format(paMessages[0], sizeof(paMessages[0]), "%s has no team ranks in the specified range", pData->m_Name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CScore::ShowTimes(int ClientID, int Offset)
|
||||
{
|
||||
if(RateLimitPlayer(ClientID))
|
||||
|
|
|
@ -290,6 +290,7 @@ class CScore
|
|||
static bool ShowTeamRankThread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
static bool ShowTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
static bool ShowTeamTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
static bool ShowPlayerTeamTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
static bool ShowTimesThread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
static bool ShowPointsThread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
static bool ShowTopPointsThread(IDbConnection *pSqlServer, const ISqlData *pGameData);
|
||||
|
@ -340,6 +341,7 @@ public:
|
|||
void ShowRank(int ClientID, const char *pName);
|
||||
|
||||
void ShowTeamTop5(int ClientID, int Offset = 1);
|
||||
void ShowTeamTop5(int ClientID, const char *pName, int Offset = 1);
|
||||
void ShowTeamRank(int ClientID, const char *pName);
|
||||
|
||||
void ShowTopPoints(int ClientID, int Offset = 1);
|
||||
|
|
Loading…
Reference in a new issue