about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/server/server.cpp72
1 files changed, 43 insertions, 29 deletions
diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp
index 4f3567cf..c283af20 100644
--- a/src/engine/server/server.cpp
+++ b/src/engine/server/server.cpp
@@ -37,23 +37,45 @@
 	#include <windows.h>
 #endif
 
-static const char *StrLtrim(const char *pStr)
+static const char *StrUTF8Ltrim(const char *pStr)
 {
-	while(*pStr && *pStr >= 0 && *pStr <= 32)
-		pStr++;
+	while(*pStr)
+	{
+		const char *pStrOld = pStr;
+		int Code = str_utf8_decode(&pStr);
+
+		// check if unicode is not empty
+		if(Code > 0x20 && Code != 0xA0 && Code != 0x034F && (Code < 0x2000 || Code > 0x200F) && (Code < 0x2028 || Code > 0x202F) &&
+			(Code < 0x205F || Code > 0x2064) && (Code < 0x206A || Code > 0x206F) && (Code < 0xFE00 || Code > 0xFE0F) &&
+			Code != 0xFEFF && (Code < 0xFFF9 || Code > 0xFFFC))
+		{
+			return pStrOld;
+		}
+	}
 	return pStr;
 }
 
-static void StrRtrim(char *pStr)
+static void StrUTF8Rtrim(char *pStr)
 {
-	int i = str_length(pStr);
-	while(i >= 0)
+	const char *p = pStr;
+	const char *pEnd = 0;
+	while(*p)
 	{
-		if(pStr[i] < 0 || pStr[i] > 32)
-			break;
-		pStr[i] = 0;
-		i--;
+		const char *pStrOld = p;
+		int Code = str_utf8_decode(&p);
+
+		// check if unicode is not empty
+		if(Code > 0x20 && Code != 0xA0 && Code != 0x034F && (Code < 0x2000 || Code > 0x200F) && (Code < 0x2028 || Code > 0x202F) &&
+			(Code < 0x205F || Code > 0x2064) && (Code < 0x206A || Code > 0x206F) && (Code < 0xFE00 || Code > 0xFE0F) &&
+			Code != 0xFEFF && (Code < 0xFFF9 || Code > 0xFFFC))
+		{
+			pEnd = 0;
+		}
+		else if(pEnd == 0)
+			pEnd = pStrOld;
 	}
+	if(pEnd != 0)
+		*(const_cast<char *>(pEnd)) = 0;
 }
 
 
@@ -326,12 +348,8 @@ int CServer::TrySetClientName(int ClientID, const char *pName)
 	char aTrimmedName[64];
 
 	// trim the name
-	str_copy(aTrimmedName, StrLtrim(pName), sizeof(aTrimmedName));
-	StrRtrim(aTrimmedName);
-
-	// check for empty names
-	if(!aTrimmedName[0])
-		return -1;
+	str_copy(aTrimmedName, StrUTF8Ltrim(pName), sizeof(aTrimmedName));
+	StrUTF8Rtrim(aTrimmedName);
 
 	// check if new and old name are the same
 	if(m_aClients[ClientID].m_aName[0] && str_comp(m_aClients[ClientID].m_aName, aTrimmedName) == 0)
@@ -342,6 +360,11 @@ int CServer::TrySetClientName(int ClientID, const char *pName)
 	Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
 	pName = aTrimmedName;
 
+
+	// check for empty names
+	if(!pName[0])
+		return -1;
+
 	// make sure that two clients doesn't have the same name
 	for(int i = 0; i < MAX_CLIENTS; i++)
 		if(i != ClientID && m_aClients[i].m_State >= CClient::STATE_READY)
@@ -365,23 +388,14 @@ void CServer::SetClientName(int ClientID, const char *pName)
 	if(!pName)
 		return;
 
-	char aCleanName[MAX_NAME_LENGTH];
-	str_copy(aCleanName, pName, sizeof(aCleanName));
-
-	// clear name
-	for(char *p = aCleanName; *p; ++p)
-	{
-		if(*p < 32)
-			*p = ' ';
-	}
-
-	if(TrySetClientName(ClientID, aCleanName))
+	char aNameTry[MAX_NAME_LENGTH];
+	str_copy(aNameTry, pName, MAX_NAME_LENGTH);
+	if(TrySetClientName(ClientID, aNameTry))
 	{
 		// auto rename
 		for(int i = 1;; i++)
 		{
-			char aNameTry[MAX_NAME_LENGTH];
-			str_format(aNameTry, sizeof(aCleanName), "(%d)%s", i, aCleanName);
+			str_format(aNameTry, MAX_NAME_LENGTH, "(%d)%s", i, pName);
 			if(TrySetClientName(ClientID, aNameTry) == 0)
 				break;
 		}