From dd62629ee9b151bf73a706604cc051276af4c83c Mon Sep 17 00:00:00 2001 From: Learath Date: Tue, 16 Apr 2019 01:47:12 +0200 Subject: [PATCH 1/2] Clean statboard chat parsing a bit --- src/game/client/components/statboard.cpp | 32 +++++++----------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/src/game/client/components/statboard.cpp b/src/game/client/components/statboard.cpp index 146e25e83..007de142d 100644 --- a/src/game/client/components/statboard.cpp +++ b/src/game/client/components/statboard.cpp @@ -77,32 +77,18 @@ void CStatboard::OnMessage(int MsgType, void *pRawMsg) { const char *p; const char *pLookFor = "flag was captured by '"; - if(str_find(pMsg->m_pMessage, pLookFor) != 0) + if((p = str_find(pMsg->m_pMessage, pLookFor))) { - // server info - CServerInfo CurrentServerInfo; - Client()->GetServerInfo(&CurrentServerInfo); - - p = str_find(pMsg->m_pMessage, pLookFor); - char aName[64]; + char aName[MAX_NAME_LENGTH]; p += str_length(pLookFor); str_copy(aName, p, sizeof(aName)); - // remove capture time - if(str_endswith(aName, " seconds)")) - { - char *c = aName+str_length(aName)-10; - while(c > aName) - { - c--; - if(*c == '(') - { - *(c-1) = 0; - break; - } - } - } - // remove the ' at the end - aName[str_length(aName)-1] = 0; + + p = str_find(aName, "'"); + if(!p) + return; + + // Remove the last "'" + aName[p - &aName[0]]= '\0'; for(int i = 0; i < MAX_CLIENTS; i++) { From 843dc29a88702853b52b2e9f0fcfe449be0d3601 Mon Sep 17 00:00:00 2001 From: Learath Date: Tue, 16 Apr 2019 02:24:24 +0200 Subject: [PATCH 2/2] Names can include quotes :/ --- src/base/system.c | 12 ++++++++ src/base/system.h | 39 ++++++++++++++++++++++-- src/game/client/components/statboard.cpp | 11 +++---- src/test/str.cpp | 14 +++++++++ 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 140db6421..261b1c1b0 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -2318,6 +2318,13 @@ void str_copy(char *dst, const char *src, int dst_size) dst[dst_size-1] = 0; /* assure null termination */ } +void str_num_copy(char *dst, const char *src, int num, int dst_size) +{ + int n = num >= dst_size ? dst_size - 1 : num; + strncpy(dst, src, n); + dst[n] = '\0'; +} + int str_length(const char *str) { return (int)strlen(str); @@ -2651,6 +2658,11 @@ const char *str_find(const char *haystack, const char *needle) return 0; } +const char *str_rchr(const char *haystack, char needle) +{ + return strrchr(haystack, needle); +} + void str_hex(char *dst, int dst_size, const void *data, int data_size) { static const char hex[] = "0123456789ABCDEF"; diff --git a/src/base/system.h b/src/base/system.h index d26d31778..a9b1ffd32 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -996,6 +996,22 @@ void str_append(char *dst, const char *src, int dst_size); */ void str_copy(char *dst, const char *src, int dst_size); +/* + Function: str_num_copy + Copies first num characters of a string to another. + + Parameters: + dst - Pointer to a buffer that shall receive the string. + src - String to be copied. + num - Number of characters to copy. + dst_size - Size of the buffer dst. + + Remarks: + - The strings are treated as zero-terminated strings. + - Guarantees that dst string will contain zero-termination. +*/ +void str_num_copy(char *dst, const char *src, int num, int dst_size); + /* Function: str_length Returns the length of a zero terminated string. @@ -1323,7 +1339,7 @@ int str_utf32_dist_buffer(const int *a, int a_len, const int *b, int b_len, int Returns: A pointer into haystack where the needle was found. - Returns NULL of needle could not be found. + Returns NULL if needle could not be found. Remarks: - Only guaranteed to work with a-z/A-Z. @@ -1342,13 +1358,30 @@ const char *str_find_nocase(const char *haystack, const char *needle); Returns: A pointer into haystack where the needle was found. - Returns NULL of needle could not be found. + Returns NULL if needle could not be found. Remarks: - The strings are treated as zero-terminated strings. */ const char *str_find(const char *haystack, const char *needle); +/* + Function: str_rchr + Finds the last occurance of a character + + Parameters: + haystack - String to search in + needle - Character to search for + + Returns: + A pointer into haystack where the needle was found. + Returns NULL if needle could not be found. + + Remarks: + - The strings are treated as zero-terminated strings. +*/ +const char *str_rchr(const char *haystack, char needle); + /* Function: str_hex Takes a datablock and generates a hex string of it, with spaces @@ -1701,7 +1734,7 @@ int str_utf8_comp_nocase_num(const char *a, const char *b, int num); Returns: A pointer into haystack where the needle was found. - Returns NULL of needle could not be found. + Returns NULL if needle could not be found. Remarks: - The strings are treated as zero-terminated strings. diff --git a/src/game/client/components/statboard.cpp b/src/game/client/components/statboard.cpp index 007de142d..de851be83 100644 --- a/src/game/client/components/statboard.cpp +++ b/src/game/client/components/statboard.cpp @@ -75,20 +75,17 @@ void CStatboard::OnMessage(int MsgType, void *pRawMsg) CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; if(pMsg->m_ClientID < 0) { - const char *p; + const char *p, *t; const char *pLookFor = "flag was captured by '"; if((p = str_find(pMsg->m_pMessage, pLookFor))) { char aName[MAX_NAME_LENGTH]; p += str_length(pLookFor); - str_copy(aName, p, sizeof(aName)); + t = str_rchr(p, '\''); - p = str_find(aName, "'"); - if(!p) + if(t <= p) return; - - // Remove the last "'" - aName[p - &aName[0]]= '\0'; + str_num_copy(aName, p, t - p, sizeof(aName)); for(int i = 0; i < MAX_CLIENTS; i++) { diff --git a/src/test/str.cpp b/src/test/str.cpp index a95788b25..b3c119b73 100644 --- a/src/test/str.cpp +++ b/src/test/str.cpp @@ -179,3 +179,17 @@ TEST(Str, StrFormat) EXPECT_EQ(str_format(aBuf, 4, "%d: ", 99), 3); EXPECT_STREQ(aBuf, "99:"); } + +TEST(Str, StrNumCopy) +{ + const char *foo = "Foobar"; + char aBuf[64]; + str_num_copy(aBuf, foo, 1, 3); + EXPECT_STREQ(aBuf, "F"); + str_num_copy(aBuf, foo, 2, 3); + EXPECT_STREQ(aBuf, "Fo"); + str_num_copy(aBuf, foo, 3, 3); + EXPECT_STREQ(aBuf, "Fo"); + str_num_copy(aBuf, foo, 6, sizeof(aBuf)); + EXPECT_STREQ(aBuf, "Foobar"); +}