mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #6585
6585: Add client_score_kind field to serverinfo (followup) r=Robyt3 a=edg-l followup on #5960 (fixes conflicts) It specifies whether the scores are to be interpreted as times (string value starting with "time") or as points (string value starting with "points"). ## 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 (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [ ] 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: heinrich5991 <heinrich5991@gmail.com> Co-authored-by: Edgar Luque <git@edgarluque.com>
This commit is contained in:
commit
03d17a98ed
|
@ -299,7 +299,7 @@ void CServer::CClient::Reset()
|
|||
m_LastAckedSnapshot = -1;
|
||||
m_LastInputTick = -1;
|
||||
m_SnapRate = CClient::SNAPRATE_INIT;
|
||||
m_Score = 0;
|
||||
m_Score = -1;
|
||||
m_NextMapChunk = 0;
|
||||
m_Flags = 0;
|
||||
}
|
||||
|
@ -2017,7 +2017,7 @@ void CServer::CacheServerInfo(CCache *pCache, int Type, bool SendClients)
|
|||
q.AddString(ClientClan(i), MAX_CLAN_LENGTH); // client clan
|
||||
|
||||
ADD_INT(q, m_aClients[i].m_Country); // client country
|
||||
ADD_INT(q, m_aClients[i].m_Score); // client score
|
||||
ADD_INT(q, m_aClients[i].m_Score == -1 ? -9999 : m_aClients[i].m_Score == 9999 ? -10000 : -m_aClients[i].m_Score); // client score
|
||||
ADD_INT(q, GameServer()->IsClientPlayer(i) ? 1 : 0); // is player?
|
||||
if(Type == SERVERINFO_EXTENDED)
|
||||
q.AddString("", 0); // extra info, reserved
|
||||
|
@ -2099,7 +2099,7 @@ void CServer::CacheServerInfoSixup(CCache *pCache, bool SendClients)
|
|||
Packer.AddString(ClientName(i), MAX_NAME_LENGTH); // client name
|
||||
Packer.AddString(ClientClan(i), MAX_CLAN_LENGTH); // client clan
|
||||
Packer.AddInt(m_aClients[i].m_Country); // client country
|
||||
Packer.AddInt(m_aClients[i].m_Score == -9999 ? -1 : -m_aClients[i].m_Score); // client score
|
||||
Packer.AddInt(m_aClients[i].m_Score); // client score
|
||||
Packer.AddInt(GameServer()->IsClientPlayer(i) ? 0 : 1); // flag spectator=1, bot=2 (player=0)
|
||||
}
|
||||
}
|
||||
|
@ -2230,6 +2230,7 @@ void CServer::UpdateRegisterServerInfo()
|
|||
"\"size\":%d"
|
||||
"},"
|
||||
"\"version\":\"%s\","
|
||||
"\"client_score_kind\":\"time\","
|
||||
"\"clients\":[",
|
||||
MaxClients,
|
||||
MaxPlayers,
|
||||
|
@ -2266,7 +2267,7 @@ void CServer::UpdateRegisterServerInfo()
|
|||
EscapeJson(aCName, sizeof(aCName), ClientName(i)),
|
||||
EscapeJson(aCClan, sizeof(aCClan), ClientClan(i)),
|
||||
m_aClients[i].m_Country,
|
||||
m_aClients[i].m_Score,
|
||||
m_aClients[i].m_Score == -1 ? -9999 : m_aClients[i].m_Score,
|
||||
JsonBool(GameServer()->IsClientPlayer(i)),
|
||||
aExtraPlayerInfo);
|
||||
str_append(aInfo, aClientInfo, sizeof(aInfo));
|
||||
|
|
|
@ -33,6 +33,14 @@ public:
|
|||
NUM_LOCS,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CLIENT_SCORE_KIND_UNSPECIFIED,
|
||||
CLIENT_SCORE_KIND_POINTS,
|
||||
CLIENT_SCORE_KIND_TIME,
|
||||
CLIENT_SCORE_KIND_TIME_BACKCOMPAT,
|
||||
};
|
||||
|
||||
class CClient
|
||||
{
|
||||
public:
|
||||
|
@ -68,6 +76,7 @@ public:
|
|||
int m_MaxPlayers;
|
||||
int m_NumPlayers;
|
||||
int m_Flags;
|
||||
int m_ClientScoreKind;
|
||||
TRISTATE m_Favorite;
|
||||
TRISTATE m_FavoriteAllowPing;
|
||||
bool m_Official;
|
||||
|
|
|
@ -64,6 +64,7 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson)
|
|||
const json_value &ServerInfo = *pJson;
|
||||
const json_value &MaxClients = ServerInfo["max_clients"];
|
||||
const json_value &MaxPlayers = ServerInfo["max_players"];
|
||||
const json_value &ClientScoreKind = ServerInfo["client_score_kind"];
|
||||
const json_value &Passworded = ServerInfo["passworded"];
|
||||
const json_value &GameType = ServerInfo["game_type"];
|
||||
const json_value &Name = ServerInfo["name"];
|
||||
|
@ -74,6 +75,7 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson)
|
|||
Error = Error || MaxClients.type != json_integer;
|
||||
Error = Error || MaxPlayers.type != json_integer;
|
||||
Error = Error || Passworded.type != json_boolean;
|
||||
Error = Error || (ClientScoreKind.type != json_none && ClientScoreKind.type != json_string);
|
||||
Error = Error || GameType.type != json_string || str_has_cc(GameType);
|
||||
Error = Error || Name.type != json_string || str_has_cc(Name);
|
||||
Error = Error || MapName.type != json_string || str_has_cc(MapName);
|
||||
|
@ -85,6 +87,15 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson)
|
|||
}
|
||||
pOut->m_MaxClients = json_int_get(&MaxClients);
|
||||
pOut->m_MaxPlayers = json_int_get(&MaxPlayers);
|
||||
pOut->m_ClientScoreKind = CServerInfo::CLIENT_SCORE_KIND_UNSPECIFIED;
|
||||
if(ClientScoreKind.type == json_string && str_startswith(ClientScoreKind, "points"))
|
||||
{
|
||||
pOut->m_ClientScoreKind = CServerInfo::CLIENT_SCORE_KIND_POINTS;
|
||||
}
|
||||
else if(ClientScoreKind.type == json_string && str_startswith(ClientScoreKind, "time"))
|
||||
{
|
||||
pOut->m_ClientScoreKind = CServerInfo::CLIENT_SCORE_KIND_TIME;
|
||||
}
|
||||
pOut->m_Passworded = Passworded;
|
||||
str_copy(pOut->m_aGameType, GameType);
|
||||
str_copy(pOut->m_aName, Name);
|
||||
|
@ -174,6 +185,7 @@ bool CServerInfo2::operator==(const CServerInfo2 &Other) const
|
|||
Unequal = Unequal || m_NumClients != Other.m_NumClients;
|
||||
Unequal = Unequal || m_MaxPlayers != Other.m_MaxPlayers;
|
||||
Unequal = Unequal || m_NumPlayers != Other.m_NumPlayers;
|
||||
Unequal = Unequal || m_ClientScoreKind != Other.m_ClientScoreKind;
|
||||
Unequal = Unequal || m_Passworded != Other.m_Passworded;
|
||||
Unequal = Unequal || str_comp(m_aGameType, Other.m_aGameType) != 0;
|
||||
Unequal = Unequal || str_comp(m_aName, Other.m_aName) != 0;
|
||||
|
@ -206,6 +218,7 @@ CServerInfo2::operator CServerInfo() const
|
|||
Result.m_NumClients = m_NumClients;
|
||||
Result.m_MaxPlayers = m_MaxPlayers;
|
||||
Result.m_NumPlayers = m_NumPlayers;
|
||||
Result.m_ClientScoreKind = m_ClientScoreKind;
|
||||
Result.m_Flags = m_Passworded ? SERVER_FLAG_PASSWORD : 0;
|
||||
str_copy(Result.m_aGameType, m_aGameType);
|
||||
str_copy(Result.m_aName, m_aName);
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
int m_NumClients; // Indirectly serialized.
|
||||
int m_MaxPlayers;
|
||||
int m_NumPlayers; // Not serialized.
|
||||
int m_ClientScoreKind;
|
||||
bool m_Passworded;
|
||||
char m_aGameType[16];
|
||||
char m_aName[64];
|
||||
|
|
|
@ -1091,6 +1091,19 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View)
|
|||
s_ListBox.DoAutoSpacing(1.0f);
|
||||
s_ListBox.DoStart(25.0f, pSelectedServer->m_NumReceivedClients, 1, 3, -1, &ServerScoreBoard);
|
||||
|
||||
int ClientScoreKind = pSelectedServer->m_ClientScoreKind;
|
||||
if(ClientScoreKind == CServerInfo::CLIENT_SCORE_KIND_UNSPECIFIED)
|
||||
{
|
||||
if((str_find_nocase(pSelectedServer->m_aGameType, "race") || str_find_nocase(pSelectedServer->m_aGameType, "fastcap")) && g_Config.m_ClDDRaceScoreBoard)
|
||||
{
|
||||
ClientScoreKind = CServerInfo::CLIENT_SCORE_KIND_TIME_BACKCOMPAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientScoreKind = CServerInfo::CLIENT_SCORE_KIND_POINTS;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < pSelectedServer->m_NumReceivedClients; i++)
|
||||
{
|
||||
const CServerInfo::CClient &CurrentClient = pSelectedServer->m_aClients[i];
|
||||
|
@ -1119,16 +1132,38 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View)
|
|||
char aTemp[16];
|
||||
|
||||
if(!CurrentClient.m_Player)
|
||||
str_copy(aTemp, "SPEC");
|
||||
else if((str_find_nocase(pSelectedServer->m_aGameType, "race") || str_find_nocase(pSelectedServer->m_aGameType, "fastcap")) && g_Config.m_ClDDRaceScoreBoard)
|
||||
{
|
||||
if(CurrentClient.m_Score == -9999 || CurrentClient.m_Score == 0)
|
||||
aTemp[0] = 0;
|
||||
else
|
||||
str_time((int64_t)absolute(CurrentClient.m_Score) * 100, TIME_HOURS, aTemp, sizeof(aTemp));
|
||||
str_copy(aTemp, "SPEC");
|
||||
}
|
||||
else if(ClientScoreKind == CServerInfo::CLIENT_SCORE_KIND_POINTS)
|
||||
{
|
||||
str_format(aTemp, sizeof(aTemp), "%d", CurrentClient.m_Score);
|
||||
}
|
||||
else
|
||||
str_format(aTemp, sizeof(aTemp), "%d", CurrentClient.m_Score);
|
||||
{
|
||||
bool Empty = false;
|
||||
int Time;
|
||||
|
||||
if(ClientScoreKind == CServerInfo::CLIENT_SCORE_KIND_TIME_BACKCOMPAT)
|
||||
{
|
||||
Time = abs(CurrentClient.m_Score);
|
||||
Empty = Time == 0 || Time == 9999;
|
||||
}
|
||||
else
|
||||
{
|
||||
Time = CurrentClient.m_Score;
|
||||
Empty = Time < 0;
|
||||
}
|
||||
|
||||
if(!Empty)
|
||||
{
|
||||
str_time((int64_t)Time * 100, TIME_HOURS, aTemp, sizeof(aTemp));
|
||||
}
|
||||
else
|
||||
{
|
||||
aTemp[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
float ScoreFontSize = 12.0f;
|
||||
while(ScoreFontSize >= 4.0f && TextRender()->TextWidth(ScoreFontSize, aTemp, -1, -1.0f) > Score.w)
|
||||
|
|
|
@ -119,8 +119,7 @@ void CPlayer::Reset()
|
|||
m_DND = false;
|
||||
|
||||
m_LastPause = 0;
|
||||
m_Score = -9999;
|
||||
m_HasFinishScore = false;
|
||||
m_Score = -1;
|
||||
|
||||
// Variable initialized:
|
||||
m_Last_Team = 0;
|
||||
|
@ -337,11 +336,11 @@ void CPlayer::Snap(int SnappingClient)
|
|||
|
||||
int SnappingClientVersion = GameServer()->GetClientVersion(SnappingClient);
|
||||
int Latency = SnappingClient == SERVER_DEMO_CLIENT ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aCurLatency[m_ClientID];
|
||||
int Score = absolute(m_Score) * -1;
|
||||
int Score = m_Score;
|
||||
|
||||
// send 0 if times of others are not shown
|
||||
if(SnappingClient != m_ClientID && g_Config.m_SvHideScore)
|
||||
Score = -9999;
|
||||
Score = -1;
|
||||
|
||||
if(!Server()->IsSixup(SnappingClient))
|
||||
{
|
||||
|
@ -350,7 +349,10 @@ void CPlayer::Snap(int SnappingClient)
|
|||
return;
|
||||
|
||||
pPlayerInfo->m_Latency = Latency;
|
||||
pPlayerInfo->m_Score = Score;
|
||||
// -9999 stands for no time and isn't displayed in scoreboard, so
|
||||
// shift the time by a second if the player actually took 9999
|
||||
// seconds to finish the map.
|
||||
pPlayerInfo->m_Score = Score == -1 ? -9999 : Score == 9999 ? -10000 : -Score;
|
||||
pPlayerInfo->m_Local = (int)(m_ClientID == SnappingClient && (m_Paused != PAUSE_PAUSED || SnappingClientVersion >= VERSION_DDNET_OLD));
|
||||
pPlayerInfo->m_ClientID = id;
|
||||
pPlayerInfo->m_Team = m_Team;
|
||||
|
@ -373,7 +375,7 @@ void CPlayer::Snap(int SnappingClient)
|
|||
pPlayerInfo->m_PlayerFlags |= protocol7::PLAYERFLAG_ADMIN;
|
||||
|
||||
// Times are in milliseconds for 0.7
|
||||
pPlayerInfo->m_Score = Score == -9999 ? -1 : -Score * 1000;
|
||||
pPlayerInfo->m_Score = Score == -1 ? -1 : Score * 1000;
|
||||
pPlayerInfo->m_Latency = Latency;
|
||||
}
|
||||
|
||||
|
@ -886,13 +888,7 @@ void CPlayer::ProcessScoreResult(CScorePlayerResult &Result)
|
|||
break;
|
||||
case CScorePlayerResult::PLAYER_INFO:
|
||||
GameServer()->Score()->PlayerData(m_ClientID)->Set(Result.m_Data.m_Info.m_Time, Result.m_Data.m_Info.m_aTimeCp);
|
||||
m_Score = Result.m_Data.m_Info.m_Score;
|
||||
m_HasFinishScore = Result.m_Data.m_Info.m_HasFinishScore;
|
||||
// -9999 stands for no time and isn't displayed in scoreboard, so
|
||||
// shift the time by a second if the player actually took 9999
|
||||
// seconds to finish the map.
|
||||
if(m_HasFinishScore && m_Score == -9999)
|
||||
m_Score = -10000;
|
||||
m_Score = Result.m_Data.m_Info.m_Time;
|
||||
Server()->ExpireServerInfo();
|
||||
int Birthday = Result.m_Data.m_Info.m_Birthday;
|
||||
if(Birthday != 0 && !m_BirthdayAnnounced)
|
||||
|
|
|
@ -182,7 +182,6 @@ public:
|
|||
vec2 m_ShowDistance;
|
||||
bool m_SpecTeam;
|
||||
bool m_NinjaJetpack;
|
||||
bool m_HasFinishScore;
|
||||
|
||||
int m_ChatScore;
|
||||
|
||||
|
|
|
@ -39,10 +39,8 @@ void CScorePlayerResult::SetVariant(Variant v)
|
|||
m_Data.m_MapVote.m_aServer[0] = '\0';
|
||||
break;
|
||||
case PLAYER_INFO:
|
||||
m_Data.m_Info.m_Score = -9999;
|
||||
m_Data.m_Info.m_Birthday = 0;
|
||||
m_Data.m_Info.m_HasFinishScore = false;
|
||||
m_Data.m_Info.m_Time = 0;
|
||||
m_Data.m_Info.m_Time = -1;
|
||||
for(float &TimeCp : m_Data.m_Info.m_aTimeCp)
|
||||
TimeCp = 0;
|
||||
}
|
||||
|
@ -167,8 +165,6 @@ bool CScoreWorker::LoadPlayerData(IDbConnection *pSqlServer, const ISqlData *pGa
|
|||
// get the best time
|
||||
float Time = pSqlServer->GetFloat(1);
|
||||
pResult->m_Data.m_Info.m_Time = Time;
|
||||
pResult->m_Data.m_Info.m_Score = -Time;
|
||||
pResult->m_Data.m_Info.m_HasFinishScore = true;
|
||||
}
|
||||
|
||||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||
|
|
|
@ -45,10 +45,8 @@ struct CScorePlayerResult : ISqlResult
|
|||
char m_aBroadcast[1024];
|
||||
struct
|
||||
{
|
||||
float m_Time;
|
||||
float m_Time; // -1 for no time.
|
||||
float m_aTimeCp[NUM_CHECKPOINTS];
|
||||
int m_Score;
|
||||
int m_HasFinishScore;
|
||||
int m_Birthday; // 0 indicates no birthday
|
||||
} m_Info;
|
||||
struct
|
||||
|
|
|
@ -818,10 +818,9 @@ void CGameTeams::OnFinish(CPlayer *Player, float Time, const char *pTimestamp)
|
|||
}
|
||||
|
||||
int TTime = 0 - (int)Time;
|
||||
if(Player->m_Score < TTime || !Player->m_HasFinishScore)
|
||||
if(Player->m_Score == -1 || Player->m_Score < TTime)
|
||||
{
|
||||
Player->m_Score = TTime;
|
||||
Player->m_HasFinishScore = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ TEST_P(SingleScore, LoadPlayerData)
|
|||
ASSERT_FALSE(CScoreWorker::LoadPlayerData(m_pConn, &m_PlayerRequest, m_aError, sizeof(m_aError))) << m_aError;
|
||||
|
||||
EXPECT_EQ(m_pPlayerResult->m_MessageKind, CScorePlayerResult::PLAYER_INFO);
|
||||
ASSERT_EQ(m_pPlayerResult->m_Data.m_Info.m_Time, 0.0);
|
||||
ASSERT_EQ(m_pPlayerResult->m_Data.m_Info.m_Time, -1.0);
|
||||
for(auto &Time : m_pPlayerResult->m_Data.m_Info.m_aTimeCp)
|
||||
{
|
||||
ASSERT_EQ(Time, 0);
|
||||
|
@ -205,7 +205,7 @@ TEST_P(SingleScore, LoadPlayerData)
|
|||
ASSERT_FALSE(CScoreWorker::LoadPlayerData(m_pConn, &m_PlayerRequest, m_aError, sizeof(m_aError))) << m_aError;
|
||||
|
||||
EXPECT_EQ(m_pPlayerResult->m_MessageKind, CScorePlayerResult::PLAYER_INFO);
|
||||
ASSERT_EQ(m_pPlayerResult->m_Data.m_Info.m_Time, 0.0);
|
||||
ASSERT_EQ(m_pPlayerResult->m_Data.m_Info.m_Time, -1.0);
|
||||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||
{
|
||||
ASSERT_EQ(m_pPlayerResult->m_Data.m_Info.m_aTimeCp[i], i);
|
||||
|
|
Loading…
Reference in a new issue