mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge #6739
6739: Add templated `str_append` function for arrays with fixed size, add tests, ensure proper buffer size is used with DDNet server filter r=def- a=Robyt3 ## Checklist - [X] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [X] Written a unit test (especially base/) or added coverage to integration test - [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: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
commit
0d45120f5c
|
@ -3991,7 +3991,7 @@ int open_file(const char *path)
|
|||
{
|
||||
if(!fs_getcwd(workingDir, sizeof(workingDir)))
|
||||
return 0;
|
||||
str_append(workingDir, "/", sizeof(workingDir));
|
||||
str_append(workingDir, "/");
|
||||
}
|
||||
else
|
||||
workingDir[0] = '\0';
|
||||
|
|
|
@ -1194,6 +1194,23 @@ std::string windows_format_system_message(unsigned long error);
|
|||
*/
|
||||
void str_append(char *dst, const char *src, int dst_size);
|
||||
|
||||
/**
|
||||
* Appends a string to a fixed-size array of chars.
|
||||
*
|
||||
* @ingroup Strings
|
||||
*
|
||||
* @param dst Array that shall receive the string.
|
||||
* @param src String to append.
|
||||
*
|
||||
* @remark The strings are treated as zero-terminated strings.
|
||||
* @remark Guarantees that dst string will contain zero-termination.
|
||||
*/
|
||||
template<int N>
|
||||
void str_append(char (&dst)[N], const char *src)
|
||||
{
|
||||
str_append(dst, src, N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a string to another.
|
||||
*
|
||||
|
@ -1210,6 +1227,23 @@ void str_append(char *dst, const char *src, int dst_size);
|
|||
*/
|
||||
int str_copy(char *dst, const char *src, int dst_size);
|
||||
|
||||
/**
|
||||
* Copies a string to a fixed-size array of chars.
|
||||
*
|
||||
* @ingroup Strings
|
||||
*
|
||||
* @param dst Array that shall receive the string.
|
||||
* @param src String to be copied.
|
||||
*
|
||||
* @remark The strings are treated as zero-terminated strings.
|
||||
* @remark Guarantees that dst string will contain zero-termination.
|
||||
*/
|
||||
template<int N>
|
||||
void str_copy(char (&dst)[N], const char *src)
|
||||
{
|
||||
str_copy(dst, src, N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates a utf8 encoded string to a given length.
|
||||
*
|
||||
|
@ -2780,23 +2814,6 @@ bool shell_unregister_application(const char *executable, bool *updated);
|
|||
void shell_update();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copies a string to a fixed-size array of chars.
|
||||
*
|
||||
* @ingroup Strings
|
||||
*
|
||||
* @param dst Array that shall receive the string.
|
||||
* @param src String to be copied.
|
||||
*
|
||||
* @remark The strings are treated as zero-terminated strings.
|
||||
* @remark Guarantees that dst string will contain zero-termination.
|
||||
*/
|
||||
template<int N>
|
||||
void str_copy(char (&dst)[N], const char *src)
|
||||
{
|
||||
str_copy(dst, src, N);
|
||||
}
|
||||
|
||||
template<>
|
||||
struct std::hash<NETADDR>
|
||||
{
|
||||
|
|
|
@ -2165,7 +2165,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
if(g_Config.m_ClRunOnJoin[0])
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), ";%s", g_Config.m_ClRunOnJoin);
|
||||
str_append(aBufMsg, aBuf, sizeof(aBufMsg));
|
||||
str_append(aBufMsg, aBuf);
|
||||
}
|
||||
if(g_Config.m_ClDummyDefaultEyes || g_Config.m_ClPlayerDefaultEyes)
|
||||
{
|
||||
|
@ -2195,7 +2195,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
if(aBufEmote[0])
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), ";%s", aBufEmote);
|
||||
str_append(aBufMsg, aBuf, sizeof(aBufMsg));
|
||||
str_append(aBufMsg, aBuf);
|
||||
}
|
||||
}
|
||||
MsgP.m_pMessage = aBufMsg;
|
||||
|
@ -4892,8 +4892,8 @@ void CClient::RequestDDNetInfo()
|
|||
{
|
||||
char aEscaped[128];
|
||||
EscapeUrl(aEscaped, sizeof(aEscaped), PlayerName());
|
||||
str_append(aUrl, "?name=", sizeof(aUrl));
|
||||
str_append(aUrl, aEscaped, sizeof(aUrl));
|
||||
str_append(aUrl, "?name=");
|
||||
str_append(aUrl, aEscaped);
|
||||
}
|
||||
|
||||
// Use ipv4 so we can know the ingame ip addresses of players before they join game servers
|
||||
|
|
|
@ -168,13 +168,13 @@ void CFriends::ConfigSaveCallback(IConfigManager *pConfigManager, void *pUserDat
|
|||
{
|
||||
str_copy(aBuf, pSelf->m_Foes ? "add_foe " : "add_friend ");
|
||||
|
||||
str_append(aBuf, "\"", sizeof(aBuf));
|
||||
str_append(aBuf, "\"");
|
||||
char *pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pSelf->m_aFriends[i].m_aName, pEnd);
|
||||
str_append(aBuf, "\" \"", sizeof(aBuf));
|
||||
str_append(aBuf, "\" \"");
|
||||
pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pSelf->m_aFriends[i].m_aClan, pEnd);
|
||||
str_append(aBuf, "\"", sizeof(aBuf));
|
||||
str_append(aBuf, "\"");
|
||||
|
||||
pConfigManager->WriteLine(aBuf);
|
||||
}
|
||||
|
|
|
@ -672,13 +672,13 @@ int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int Sto
|
|||
{
|
||||
if(!First)
|
||||
{
|
||||
str_append(Warning.m_aWarningMsg, ", ", sizeof(Warning.m_aWarningMsg));
|
||||
str_append(Warning.m_aWarningMsg, ", ");
|
||||
}
|
||||
str_append(Warning.m_aWarningMsg, EXPLANATION[i], sizeof(Warning.m_aWarningMsg));
|
||||
str_append(Warning.m_aWarningMsg, EXPLANATION[i]);
|
||||
First = false;
|
||||
}
|
||||
}
|
||||
str_append(Warning.m_aWarningMsg, " unsupported", sizeof(Warning.m_aWarningMsg));
|
||||
str_append(Warning.m_aWarningMsg, " unsupported");
|
||||
m_vWarnings.emplace_back(Warning);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1415,17 +1415,17 @@ int CServerBrowser::LoadingProgression() const
|
|||
return 100.0f * Loaded / Servers;
|
||||
}
|
||||
|
||||
void CServerBrowser::DDNetFilterAdd(char *pFilter, const char *pName)
|
||||
void CServerBrowser::DDNetFilterAdd(char *pFilter, int FilterSize, const char *pName) const
|
||||
{
|
||||
if(DDNetFiltered(pFilter, pName))
|
||||
return;
|
||||
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), ",%s", pName);
|
||||
str_append(pFilter, aBuf, 128);
|
||||
str_append(pFilter, aBuf, FilterSize);
|
||||
}
|
||||
|
||||
void CServerBrowser::DDNetFilterRem(char *pFilter, const char *pName)
|
||||
void CServerBrowser::DDNetFilterRem(char *pFilter, int FilterSize, const char *pName) const
|
||||
{
|
||||
if(!DDNetFiltered(pFilter, pName))
|
||||
return;
|
||||
|
@ -1443,12 +1443,12 @@ void CServerBrowser::DDNetFilterRem(char *pFilter, const char *pName)
|
|||
{
|
||||
char aBuf2[128];
|
||||
str_format(aBuf2, sizeof(aBuf2), ",%s", aToken);
|
||||
str_append(pFilter, aBuf2, 128);
|
||||
str_append(pFilter, aBuf2, FilterSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CServerBrowser::DDNetFiltered(char *pFilter, const char *pName)
|
||||
bool CServerBrowser::DDNetFiltered(const char *pFilter, const char *pName) const
|
||||
{
|
||||
return str_in_list(pFilter, ",", pName); // country not excluded
|
||||
}
|
||||
|
@ -1468,7 +1468,7 @@ void CServerBrowser::CountryFilterClean(int Network)
|
|||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), ",%s", pName);
|
||||
str_append(aNewList, aBuf, sizeof(aNewList));
|
||||
str_append(aNewList, aBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1489,7 +1489,7 @@ void CServerBrowser::TypeFilterClean(int Network)
|
|||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), ",%s", pName);
|
||||
str_append(aNewList, aBuf, sizeof(aNewList));
|
||||
str_append(aNewList, aBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,9 +114,9 @@ public:
|
|||
int NumTypes(int Network) override { return m_aNetworks[Network].m_NumTypes; }
|
||||
const char *GetType(int Network, int Index) override { return m_aNetworks[Network].m_aTypes[Index]; }
|
||||
|
||||
void DDNetFilterAdd(char *pFilter, const char *pName) override;
|
||||
void DDNetFilterRem(char *pFilter, const char *pName) override;
|
||||
bool DDNetFiltered(char *pFilter, const char *pName) override;
|
||||
void DDNetFilterAdd(char *pFilter, int FilterSize, const char *pName) const override;
|
||||
void DDNetFilterRem(char *pFilter, int FilterSize, const char *pName) const override;
|
||||
bool DDNetFiltered(const char *pFilter, const char *pName) const override;
|
||||
void CountryFilterClean(int Network) override;
|
||||
void TypeFilterClean(int Network) override;
|
||||
|
||||
|
|
|
@ -1031,7 +1031,7 @@ public:
|
|||
void AppendTextContainer(STextContainerIndex TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override
|
||||
{
|
||||
STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
|
||||
str_append(TextContainer.m_aDebugText, pText, sizeof(TextContainer.m_aDebugText));
|
||||
str_append(TextContainer.m_aDebugText, pText);
|
||||
|
||||
// calculate the font size of the displayed glyphs
|
||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||
|
|
|
@ -315,7 +315,7 @@ void CUpdater::PerformUpdate()
|
|||
char aBuf[512];
|
||||
str_copy(aBuf, pFile, sizeof(aBuf)); // SDL
|
||||
str_copy(aBuf + len - 4, "-" PLAT_NAME, sizeof(aBuf) - len + 4); // -win32
|
||||
str_append(aBuf, pFile + len - 4, sizeof(aBuf)); // .dll
|
||||
str_append(aBuf, pFile + len - 4); // .dll
|
||||
FetchFile(aBuf, pFile);
|
||||
#endif
|
||||
// Ignore DLL downloads on other platforms
|
||||
|
@ -326,7 +326,7 @@ void CUpdater::PerformUpdate()
|
|||
char aBuf[512];
|
||||
str_copy(aBuf, pFile, sizeof(aBuf)); // libsteam_api
|
||||
str_copy(aBuf + len - 3, "-" PLAT_NAME, sizeof(aBuf) - len + 3); // -linux-x86_64
|
||||
str_append(aBuf, pFile + len - 3, sizeof(aBuf)); // .so
|
||||
str_append(aBuf, pFile + len - 3); // .so
|
||||
FetchFile(aBuf, pFile);
|
||||
#endif
|
||||
// Ignore DLL downloads on other platforms, on Linux we statically link anyway
|
||||
|
|
|
@ -1293,11 +1293,11 @@ void CServer::SendRconLogLine(int ClientID, const CLogMessage *pMessage)
|
|||
{
|
||||
str_append(aLine, pLine, pStart - pLine + 1);
|
||||
str_append(aLine, pStart + 2, pStart - pLine + pEnd - pStart - 1);
|
||||
str_append(aLine, pEnd + 2, sizeof(aLine));
|
||||
str_append(aLine, pEnd + 2);
|
||||
|
||||
str_append(aLineWithoutIps, pLine, pStart - pLine + 1);
|
||||
str_append(aLineWithoutIps, "XXX", sizeof(aLineWithoutIps));
|
||||
str_append(aLineWithoutIps, pEnd + 2, sizeof(aLineWithoutIps));
|
||||
str_append(aLineWithoutIps, "XXX");
|
||||
str_append(aLineWithoutIps, pEnd + 2);
|
||||
|
||||
pLine = aLine;
|
||||
pLineWithoutIps = aLineWithoutIps;
|
||||
|
@ -2319,12 +2319,12 @@ void CServer::UpdateRegisterServerInfo()
|
|||
m_aClients[i].m_Score.value_or(-9999),
|
||||
JsonBool(GameServer()->IsClientPlayer(i)),
|
||||
aExtraPlayerInfo);
|
||||
str_append(aInfo, aClientInfo, sizeof(aInfo));
|
||||
str_append(aInfo, aClientInfo);
|
||||
FirstPlayer = false;
|
||||
}
|
||||
}
|
||||
|
||||
str_append(aInfo, "]}", sizeof(aInfo));
|
||||
str_append(aInfo, "]}");
|
||||
|
||||
m_pRegister->OnNewInfo(aInfo);
|
||||
}
|
||||
|
|
|
@ -165,9 +165,9 @@ public:
|
|||
virtual int NumTypes(int Network) = 0;
|
||||
virtual const char *GetType(int Network, int Index) = 0;
|
||||
|
||||
virtual void DDNetFilterAdd(char *pFilter, const char *pName) = 0;
|
||||
virtual void DDNetFilterRem(char *pFilter, const char *pName) = 0;
|
||||
virtual bool DDNetFiltered(char *pFilter, const char *pName) = 0;
|
||||
virtual void DDNetFilterAdd(char *pFilter, int FilterSize, const char *pName) const = 0;
|
||||
virtual void DDNetFilterRem(char *pFilter, int FilterSize, const char *pName) const = 0;
|
||||
virtual bool DDNetFiltered(const char *pFilter, const char *pName) const = 0;
|
||||
virtual void CountryFilterClean(int Network) = 0;
|
||||
virtual void TypeFilterClean(int Network) = 0;
|
||||
virtual int GetCurrentType() = 0;
|
||||
|
|
|
@ -732,9 +732,9 @@ void CConsole::ConCommandStatus(IResult *pResult, void *pUser)
|
|||
if(Used > 0)
|
||||
{
|
||||
Used += 2;
|
||||
str_append(aBuf, ", ", sizeof(aBuf));
|
||||
str_append(aBuf, ", ");
|
||||
}
|
||||
str_append(aBuf, pCommand->m_pName, sizeof(aBuf));
|
||||
str_append(aBuf, pCommand->m_pName);
|
||||
Used += Length;
|
||||
}
|
||||
else
|
||||
|
@ -927,7 +927,7 @@ void CConsole::ConToggle(IConsole::IResult *pResult, void *pUser)
|
|||
str_format(aBuf, sizeof(aBuf), "%s \"", pResult->GetString(0));
|
||||
char *pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pStr, aBuf + sizeof(aBuf));
|
||||
str_append(aBuf, "\"", sizeof(aBuf));
|
||||
str_append(aBuf, "\"");
|
||||
pConsole->ExecuteLine(aBuf);
|
||||
aBuf[0] = 0;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ void CFifo::Init(IConsole *pConsole, char *pFifoFile, int Flag)
|
|||
}
|
||||
|
||||
str_copy(m_aFilename, "\\\\.\\pipe\\");
|
||||
str_append(m_aFilename, pFifoFile, sizeof(m_aFilename));
|
||||
str_append(m_aFilename, pFifoFile);
|
||||
m_Flag = Flag;
|
||||
|
||||
const std::wstring WideFilename = windows_utf8_to_wide(m_aFilename);
|
||||
|
|
|
@ -112,7 +112,7 @@ public:
|
|||
{
|
||||
char aBuffer[IO_MAX_PATH_LENGTH];
|
||||
str_copy(aBuffer, pArgv0, Pos + 1);
|
||||
str_append(aBuffer, "/storage.cfg", sizeof(aBuffer));
|
||||
str_append(aBuffer, "/storage.cfg");
|
||||
File = io_open(aBuffer, IOFLAG_READ | IOFLAG_SKIP_BOM);
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ public:
|
|||
return;
|
||||
}
|
||||
#if defined(CONF_PLATFORM_MACOS)
|
||||
str_append(m_aBinarydir, "/../../../DDNet-Server.app/Contents/MacOS", sizeof(m_aBinarydir));
|
||||
str_append(m_aBinarydir, "/../../../DDNet-Server.app/Contents/MacOS");
|
||||
str_format(aBuf, sizeof(aBuf), "%s/" PLAT_SERVER_EXEC, m_aBinarydir);
|
||||
if(fs_is_file(aBuf))
|
||||
{
|
||||
|
|
|
@ -419,8 +419,8 @@ const char *CBinds::GetKeyBindModifiersName(int ModifierCombination)
|
|||
{
|
||||
if(ModifierCombination & (1 << k))
|
||||
{
|
||||
str_append(aModifier, GetModifierName(k), sizeof(aModifier));
|
||||
str_append(aModifier, "+", sizeof(aModifier));
|
||||
str_append(aModifier, GetModifierName(k));
|
||||
str_append(aModifier, "+");
|
||||
}
|
||||
}
|
||||
return aModifier;
|
||||
|
|
|
@ -299,17 +299,17 @@ bool CChat::OnInput(const IInput::CEvent &Event)
|
|||
str_truncate(aBuf, sizeof(aBuf), m_Input.GetString(), m_PlaceholderOffset);
|
||||
|
||||
// add the command
|
||||
str_append(aBuf, "/", sizeof(aBuf));
|
||||
str_append(aBuf, pCompletionCommand->m_pName, sizeof(aBuf));
|
||||
str_append(aBuf, "/");
|
||||
str_append(aBuf, pCompletionCommand->m_pName);
|
||||
|
||||
// add separator
|
||||
const char *pSeparator = pCompletionCommand->m_pParams[0] == '\0' ? "" : " ";
|
||||
str_append(aBuf, pSeparator, sizeof(aBuf));
|
||||
str_append(aBuf, pSeparator);
|
||||
if(*pSeparator)
|
||||
str_append(aBuf, pSeparator, sizeof(aBuf));
|
||||
str_append(aBuf, pSeparator);
|
||||
|
||||
// add part after the name
|
||||
str_append(aBuf, m_Input.GetString() + m_PlaceholderOffset + m_PlaceholderLength, sizeof(aBuf));
|
||||
str_append(aBuf, m_Input.GetString() + m_PlaceholderOffset + m_PlaceholderLength);
|
||||
|
||||
m_PlaceholderLength = str_length(pSeparator) + str_length(pCompletionCommand->m_pName) + 1;
|
||||
m_Input.Set(aBuf);
|
||||
|
@ -360,7 +360,7 @@ bool CChat::OnInput(const IInput::CEvent &Event)
|
|||
str_truncate(aBuf, sizeof(aBuf), m_Input.GetString(), m_PlaceholderOffset);
|
||||
|
||||
// add the name
|
||||
str_append(aBuf, pCompletionString, sizeof(aBuf));
|
||||
str_append(aBuf, pCompletionString);
|
||||
|
||||
// add separator
|
||||
const char *pSeparator = "";
|
||||
|
@ -369,10 +369,10 @@ bool CChat::OnInput(const IInput::CEvent &Event)
|
|||
else if(m_PlaceholderOffset == 0)
|
||||
pSeparator = ":";
|
||||
if(*pSeparator)
|
||||
str_append(aBuf, pSeparator, sizeof(aBuf));
|
||||
str_append(aBuf, pSeparator);
|
||||
|
||||
// add part after the name
|
||||
str_append(aBuf, m_Input.GetString() + m_PlaceholderOffset + m_PlaceholderLength, sizeof(aBuf));
|
||||
str_append(aBuf, m_Input.GetString() + m_PlaceholderOffset + m_PlaceholderLength);
|
||||
|
||||
m_PlaceholderLength = str_length(pSeparator) + str_length(pCompletionString);
|
||||
m_Input.Set(aBuf);
|
||||
|
@ -883,7 +883,7 @@ void CChat::OnPrepareLines()
|
|||
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
|
||||
}
|
||||
|
||||
str_append(aName, m_aLines[r].m_aName, sizeof(aName));
|
||||
str_append(aName, m_aLines[r].m_aName);
|
||||
|
||||
char aCount[12];
|
||||
if(m_aLines[r].m_ClientID < 0)
|
||||
|
|
|
@ -188,10 +188,10 @@ void CGameConsole::CInstance::PossibleArgumentsCompleteCallback(int Index, const
|
|||
// get command
|
||||
char aBuf[512];
|
||||
StrCopyUntilSpace(aBuf, sizeof(aBuf), pInstance->GetString());
|
||||
str_append(aBuf, " ", sizeof(aBuf));
|
||||
str_append(aBuf, " ");
|
||||
|
||||
// append argument
|
||||
str_append(aBuf, pStr, sizeof(aBuf));
|
||||
str_append(aBuf, pStr);
|
||||
pInstance->m_Input.Set(aBuf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1522,7 +1522,7 @@ int CMenus::Render()
|
|||
char aBufNew[IO_MAX_PATH_LENGTH];
|
||||
str_format(aBufNew, sizeof(aBufNew), "%s/%s", m_aCurrentDemoFolder, m_DemoRenameInput.GetString());
|
||||
if(!str_endswith(aBufNew, ".demo"))
|
||||
str_append(aBufNew, ".demo", sizeof(aBufNew));
|
||||
str_append(aBufNew, ".demo");
|
||||
|
||||
if(Storage()->FileExists(aBufNew, m_vDemos[m_DemolistSelectedIndex].m_StorageType))
|
||||
{
|
||||
|
|
|
@ -762,6 +762,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
|
|||
if(s_ActivePage == 1)
|
||||
{
|
||||
char *pFilterExcludeTypes = Network == IServerBrowser::NETWORK_DDNET ? g_Config.m_BrFilterExcludeTypes : g_Config.m_BrFilterExcludeTypesKoG;
|
||||
const int FilterExcludeTypesSize = Network == IServerBrowser::NETWORK_DDNET ? sizeof(g_Config.m_BrFilterExcludeTypes) : sizeof(g_Config.m_BrFilterExcludeTypesKoG);
|
||||
int MaxTypes = ServerBrowser()->NumTypes(Network);
|
||||
int NumTypes = ServerBrowser()->NumTypes(Network);
|
||||
int PerLine = 3;
|
||||
|
@ -811,7 +812,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
|
|||
for(int j = 0; j < MaxTypes; ++j)
|
||||
{
|
||||
if(j != TypeIndex)
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeTypes, ServerBrowser()->GetType(Network, j));
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeTypes, FilterExcludeTypesSize, ServerBrowser()->GetType(Network, j));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -832,11 +833,11 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
|
|||
}
|
||||
else if(Active)
|
||||
{
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeTypes, pName);
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeTypes, FilterExcludeTypesSize, pName);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerBrowser()->DDNetFilterRem(pFilterExcludeTypes, pName);
|
||||
ServerBrowser()->DDNetFilterRem(pFilterExcludeTypes, FilterExcludeTypesSize, pName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -858,6 +859,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
|
|||
else
|
||||
{
|
||||
char *pFilterExcludeCountries = Network == IServerBrowser::NETWORK_DDNET ? g_Config.m_BrFilterExcludeCountries : g_Config.m_BrFilterExcludeCountriesKoG;
|
||||
const int FilterExcludeCountriesSize = Network == IServerBrowser::NETWORK_DDNET ? sizeof(g_Config.m_BrFilterExcludeCountries) : sizeof(g_Config.m_BrFilterExcludeCountriesKoG);
|
||||
ServerFilter.HSplitTop(15.0f, &ServerFilter, &ServerFilter);
|
||||
|
||||
const float FlagWidth = 40.0f;
|
||||
|
@ -907,7 +909,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
|
|||
for(int j = 0; j < MaxFlags; ++j)
|
||||
{
|
||||
if(j != CountryIndex)
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeCountries, ServerBrowser()->GetCountryName(Network, j));
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeCountries, FilterExcludeCountriesSize, ServerBrowser()->GetCountryName(Network, j));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -928,11 +930,11 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
|
|||
}
|
||||
else if(Active)
|
||||
{
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeCountries, pName);
|
||||
ServerBrowser()->DDNetFilterAdd(pFilterExcludeCountries, FilterExcludeCountriesSize, pName);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerBrowser()->DDNetFilterRem(pFilterExcludeCountries, pName);
|
||||
ServerBrowser()->DDNetFilterRem(pFilterExcludeCountries, FilterExcludeCountriesSize, pName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -676,7 +676,7 @@ void CMenus::RenderDemoPlayerSliceSavePopup(CUIRect MainView)
|
|||
{
|
||||
char aDemoName[IO_MAX_PATH_LENGTH];
|
||||
DemoPlayer()->GetDemoName(aDemoName, sizeof(aDemoName));
|
||||
str_append(aDemoName, ".demo", sizeof(aDemoName));
|
||||
str_append(aDemoName, ".demo");
|
||||
|
||||
if(!str_endswith(m_DemoSliceInput.GetString(), ".demo"))
|
||||
m_DemoSliceInput.Append(".demo");
|
||||
|
@ -1160,8 +1160,8 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
fs_parent_dir(m_aCurrentDemoFolder);
|
||||
else // sub folder
|
||||
{
|
||||
str_append(m_aCurrentDemoFolder, "/", sizeof(m_aCurrentDemoFolder));
|
||||
str_append(m_aCurrentDemoFolder, m_vDemos[m_DemolistSelectedIndex].m_aFilename, sizeof(m_aCurrentDemoFolder));
|
||||
str_append(m_aCurrentDemoFolder, "/");
|
||||
str_append(m_aCurrentDemoFolder, m_vDemos[m_DemolistSelectedIndex].m_aFilename);
|
||||
m_DemolistStorageType = m_vDemos[m_DemolistSelectedIndex].m_StorageType;
|
||||
}
|
||||
DemolistPopulate();
|
||||
|
|
|
@ -191,7 +191,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
|
|||
while(TextRender()->TextWidth(TitleFontsize, aBuf, -1, -1.0f) > TitleWidth)
|
||||
aBuf[str_length(aBuf) - 1] = '\0';
|
||||
if(str_comp(aBuf, Client()->GetCurrentMap()))
|
||||
str_append(aBuf, "…", sizeof(aBuf));
|
||||
str_append(aBuf, "…");
|
||||
pTitle = aBuf;
|
||||
}
|
||||
}
|
||||
|
@ -531,25 +531,25 @@ void CScoreboard::RenderRecordingNotification(float x)
|
|||
{
|
||||
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_MANUAL)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
||||
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Manual"), aTime);
|
||||
str_append(aBuf, aBuf2, sizeof(aBuf));
|
||||
str_append(aBuf, aBuf2);
|
||||
}
|
||||
if(m_pClient->DemoRecorder(RECORDER_RACE)->IsRecording())
|
||||
{
|
||||
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_RACE)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
||||
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Race"), aTime);
|
||||
str_append(aBuf, aBuf2, sizeof(aBuf));
|
||||
str_append(aBuf, aBuf2);
|
||||
}
|
||||
if(m_pClient->DemoRecorder(RECORDER_AUTO)->IsRecording())
|
||||
{
|
||||
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_AUTO)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
||||
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Auto"), aTime);
|
||||
str_append(aBuf, aBuf2, sizeof(aBuf));
|
||||
str_append(aBuf, aBuf2);
|
||||
}
|
||||
if(m_pClient->DemoRecorder(RECORDER_REPLAYS)->IsRecording())
|
||||
{
|
||||
str_time((int64_t)m_pClient->DemoRecorder(RECORDER_REPLAYS)->Length() * 100, TIME_HOURS, aTime, sizeof(aTime));
|
||||
str_format(aBuf2, sizeof(aBuf2), "%s %s ", Localize("Replay"), aTime);
|
||||
str_append(aBuf, aBuf2, sizeof(aBuf));
|
||||
str_append(aBuf, aBuf2);
|
||||
}
|
||||
|
||||
if(!aBuf[0])
|
||||
|
|
|
@ -518,7 +518,7 @@ void CStatboard::FormatStats(char *pDest, size_t DestSize)
|
|||
pStats->m_FlagGrabs, // Flag grabs
|
||||
pStats->m_FlagCaptures); // Flag captures
|
||||
|
||||
str_append(aPlayerStats, aBuf, sizeof(aPlayerStats));
|
||||
str_append(aPlayerStats, aBuf);
|
||||
}
|
||||
|
||||
str_format(pDest, DestSize, "%s\n\n%s", aServerStats, aPlayerStats);
|
||||
|
|
|
@ -78,10 +78,10 @@ void CVoting::CallvoteOption(int OptionID, const char *pReason, bool ForceVote)
|
|||
str_copy(aBuf, "force_vote option \"");
|
||||
char *pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pOption->m_aDescription, aBuf + sizeof(aBuf));
|
||||
str_append(aBuf, "\" \"", sizeof(aBuf));
|
||||
str_append(aBuf, "\" \"");
|
||||
pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pReason, aBuf + sizeof(aBuf));
|
||||
str_append(aBuf, "\"", sizeof(aBuf));
|
||||
str_append(aBuf, "\"");
|
||||
Client()->Rcon(aBuf);
|
||||
}
|
||||
else
|
||||
|
@ -105,7 +105,7 @@ void CVoting::RemovevoteOption(int OptionID)
|
|||
str_copy(aBuf, "remove_vote \"");
|
||||
char *pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pOption->m_aDescription, aBuf + sizeof(aBuf));
|
||||
str_append(aBuf, "\"", sizeof(aBuf));
|
||||
str_append(aBuf, "\"");
|
||||
Client()->Rcon(aBuf);
|
||||
break;
|
||||
}
|
||||
|
@ -121,10 +121,10 @@ void CVoting::AddvoteOption(const char *pDescription, const char *pCommand)
|
|||
str_copy(aBuf, "add_vote \"");
|
||||
char *pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pDescription, aBuf + sizeof(aBuf));
|
||||
str_append(aBuf, "\" \"", sizeof(aBuf));
|
||||
str_append(aBuf, "\" \"");
|
||||
pDst = aBuf + str_length(aBuf);
|
||||
str_escape(&pDst, pCommand, aBuf + sizeof(aBuf));
|
||||
str_append(aBuf, "\"", sizeof(aBuf));
|
||||
str_append(aBuf, "\"");
|
||||
Client()->Rcon(aBuf);
|
||||
}
|
||||
|
||||
|
|
|
@ -4440,16 +4440,16 @@ void CGameContext::OnUpdatePlayerServerInfo(char *aBuf, int BufSize, int ID)
|
|||
apPartNames[i],
|
||||
EscapeJson(aCSkinName, sizeof(aCSkinName), TeeInfo.m_apSkinPartNames[i]));
|
||||
|
||||
str_append(aJsonSkin, aPartBuf, sizeof(aJsonSkin));
|
||||
str_append(aJsonSkin, aPartBuf);
|
||||
|
||||
if(TeeInfo.m_aUseCustomColors[i])
|
||||
{
|
||||
str_format(aPartBuf, sizeof(aPartBuf),
|
||||
",\"color\":%d",
|
||||
TeeInfo.m_aSkinPartColors[i]);
|
||||
str_append(aJsonSkin, aPartBuf, sizeof(aJsonSkin));
|
||||
str_append(aJsonSkin, aPartBuf);
|
||||
}
|
||||
str_append(aJsonSkin, "}", sizeof(aJsonSkin));
|
||||
str_append(aJsonSkin, "}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -581,7 +581,7 @@ char *CSaveTeam::GetString()
|
|||
{
|
||||
char aBuf[1024];
|
||||
str_format(aBuf, sizeof(aBuf), "\n%s", m_pSavedTees[i].GetString(this));
|
||||
str_append(m_aString, aBuf, sizeof(m_aString));
|
||||
str_append(m_aString, aBuf);
|
||||
}
|
||||
|
||||
if(m_pSwitchers && m_HighestSwitchNumber)
|
||||
|
@ -590,7 +590,7 @@ char *CSaveTeam::GetString()
|
|||
{
|
||||
char aBuf[64];
|
||||
str_format(aBuf, sizeof(aBuf), "\n%d\t%d\t%d", m_pSwitchers[i].m_Status, m_pSwitchers[i].m_EndTime, m_pSwitchers[i].m_Type);
|
||||
str_append(m_aString, aBuf, sizeof(m_aString));
|
||||
str_append(m_aString, aBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ bool CScoreWorker::MapVote(IDbConnection *pSqlServer, const ISqlData *pGameData,
|
|||
|
||||
char aMapPrefix[128];
|
||||
str_copy(aMapPrefix, pData->m_aName, sizeof(aMapPrefix));
|
||||
str_append(aMapPrefix, "%", sizeof(aMapPrefix));
|
||||
str_append(aMapPrefix, "%");
|
||||
|
||||
char aBuf[768];
|
||||
str_format(aBuf, sizeof(aBuf),
|
||||
|
@ -275,7 +275,7 @@ bool CScoreWorker::MapInfo(IDbConnection *pSqlServer, const ISqlData *pGameData,
|
|||
|
||||
char aMapPrefix[128];
|
||||
str_copy(aMapPrefix, pData->m_aName, sizeof(aMapPrefix));
|
||||
str_append(aMapPrefix, "%", sizeof(aMapPrefix));
|
||||
str_append(aMapPrefix, "%");
|
||||
|
||||
char aCurrentTimestamp[512];
|
||||
pSqlServer->ToUnixTimestamp("CURRENT_TIMESTAMP", aCurrentTimestamp, sizeof(aCurrentTimestamp));
|
||||
|
@ -876,12 +876,12 @@ bool CScoreWorker::ShowTeamRank(IDbConnection *pSqlServer, const ISqlData *pGame
|
|||
char aFormattedNames[512] = "";
|
||||
for(unsigned int Name = 0; Name < Teamrank.m_NumNames; Name++)
|
||||
{
|
||||
str_append(aFormattedNames, Teamrank.m_aaNames[Name], sizeof(aFormattedNames));
|
||||
str_append(aFormattedNames, Teamrank.m_aaNames[Name]);
|
||||
|
||||
if(Name < Teamrank.m_NumNames - 2)
|
||||
str_append(aFormattedNames, ", ", sizeof(aFormattedNames));
|
||||
str_append(aFormattedNames, ", ");
|
||||
else if(Name < Teamrank.m_NumNames - 1)
|
||||
str_append(aFormattedNames, " & ", sizeof(aFormattedNames));
|
||||
str_append(aFormattedNames, " & ");
|
||||
}
|
||||
|
||||
if(g_Config.m_SvHideScore)
|
||||
|
@ -1051,11 +1051,11 @@ bool CScoreWorker::ShowTeamTop5(IDbConnection *pSqlServer, const ISqlData *pGame
|
|||
{
|
||||
char aName[MAX_NAME_LENGTH];
|
||||
pSqlServer->GetString(1, aName, sizeof(aName));
|
||||
str_append(aNames, aName, sizeof(aNames));
|
||||
str_append(aNames, aName);
|
||||
if(i < TeamSize - 2)
|
||||
str_append(aNames, ", ", sizeof(aNames));
|
||||
str_append(aNames, ", ");
|
||||
else if(i == TeamSize - 2)
|
||||
str_append(aNames, " & ", sizeof(aNames));
|
||||
str_append(aNames, " & ");
|
||||
if(pSqlServer->Step(&Last, pError, ErrorSize))
|
||||
{
|
||||
return true;
|
||||
|
@ -1143,12 +1143,12 @@ bool CScoreWorker::ShowPlayerTeamTop5(IDbConnection *pSqlServer, const ISqlData
|
|||
char aFormattedNames[512] = "";
|
||||
for(unsigned int Name = 0; Name < Teamrank.m_NumNames; Name++)
|
||||
{
|
||||
str_append(aFormattedNames, Teamrank.m_aaNames[Name], sizeof(aFormattedNames));
|
||||
str_append(aFormattedNames, Teamrank.m_aaNames[Name]);
|
||||
|
||||
if(Name < Teamrank.m_NumNames - 2)
|
||||
str_append(aFormattedNames, ", ", sizeof(aFormattedNames));
|
||||
str_append(aFormattedNames, ", ");
|
||||
else if(Name < Teamrank.m_NumNames - 1)
|
||||
str_append(aFormattedNames, " & ", sizeof(aFormattedNames));
|
||||
str_append(aFormattedNames, " & ");
|
||||
}
|
||||
|
||||
str_format(paMessages[Line], sizeof(paMessages[Line]), "%d. %s Team Time: %s",
|
||||
|
@ -1776,11 +1776,11 @@ bool CScoreWorker::GetSaves(IDbConnection *pSqlServer, const ISqlData *pGameData
|
|||
auto *paMessages = pResult->m_Data.m_aaMessages;
|
||||
|
||||
char aSaveLike[128] = "";
|
||||
str_append(aSaveLike, "%\n", sizeof(aSaveLike));
|
||||
str_append(aSaveLike, "%\n");
|
||||
sqlstr::EscapeLike(aSaveLike + str_length(aSaveLike),
|
||||
pData->m_aRequestingPlayer,
|
||||
sizeof(aSaveLike) - str_length(aSaveLike));
|
||||
str_append(aSaveLike, "\t%", sizeof(aSaveLike));
|
||||
str_append(aSaveLike, "\t%");
|
||||
|
||||
char aCurrentTimestamp[512];
|
||||
pSqlServer->ToUnixTimestamp("CURRENT_TIMESTAMP", aCurrentTimestamp, sizeof(aCurrentTimestamp));
|
||||
|
|
|
@ -161,9 +161,9 @@ void CGameTeams::OnCharacterStart(int ClientID)
|
|||
if(First)
|
||||
First = false;
|
||||
else
|
||||
str_append(aBuf, ", ", sizeof(aBuf));
|
||||
str_append(aBuf, ", ");
|
||||
|
||||
str_append(aBuf, GameServer()->Server()->ClientName(i), sizeof(aBuf));
|
||||
str_append(aBuf, GameServer()->Server()->ClientName(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,9 +270,9 @@ void CGameTeams::Tick()
|
|||
{
|
||||
if(aPlayerNames[0])
|
||||
{
|
||||
str_append(aPlayerNames, ", ", sizeof(aPlayerNames));
|
||||
str_append(aPlayerNames, ", ");
|
||||
}
|
||||
str_append(aPlayerNames, Server()->ClientName(j), sizeof(aPlayerNames));
|
||||
str_append(aPlayerNames, Server()->ClientName(j));
|
||||
NumPlayersNotStarted += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -586,6 +586,37 @@ TEST(Str, Copy)
|
|||
EXPECT_STREQ(aBuf, "DDNet最好了");
|
||||
str_copy(aBuf, pStr, 16);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好了");
|
||||
str_copy(aBuf, pStr);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好了");
|
||||
}
|
||||
|
||||
TEST(Str, Append)
|
||||
{
|
||||
char aBuf[64];
|
||||
aBuf[0] = '\0';
|
||||
str_append(aBuf, "DDNet最好了", 7);
|
||||
EXPECT_STREQ(aBuf, "DDNet");
|
||||
str_append(aBuf, "最", 8);
|
||||
EXPECT_STREQ(aBuf, "DDNet");
|
||||
str_append(aBuf, "最", 9);
|
||||
EXPECT_STREQ(aBuf, "DDNet最");
|
||||
str_append(aBuf, "好", 10);
|
||||
EXPECT_STREQ(aBuf, "DDNet最");
|
||||
str_append(aBuf, "好", 11);
|
||||
EXPECT_STREQ(aBuf, "DDNet最");
|
||||
str_append(aBuf, "好", 12);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好");
|
||||
str_append(aBuf, "了", 13);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好");
|
||||
str_append(aBuf, "了", 14);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好");
|
||||
str_append(aBuf, "了", 15);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好了");
|
||||
str_append(aBuf, "了", 16);
|
||||
EXPECT_STREQ(aBuf, "DDNet最好了");
|
||||
aBuf[0] = '\0';
|
||||
str_append(aBuf, "DDNet最好了");
|
||||
EXPECT_STREQ(aBuf, "DDNet最好了");
|
||||
}
|
||||
|
||||
TEST(Str, Utf8Stats)
|
||||
|
|
|
@ -27,7 +27,7 @@ inline void ProcessItem(const char *pItemName, IStorage *pStorage)
|
|||
|
||||
str_copy(aConfig, pItemName, sizeof(aConfig));
|
||||
aConfig[Len - sizeof(".map")] = 0;
|
||||
str_append(aConfig, ".cfg", sizeof(aConfig));
|
||||
str_append(aConfig, ".cfg");
|
||||
dbg_msg("config_common", "processing '%s'", pItemName);
|
||||
Process(pStorage, pItemName, aConfig);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue