Kawe Mazidjatari b3a68ed095 Add EABase, EAThread and DirtySDK to R5sdk
DirtySDK (EA's Dirty Sockets library) will be used for the LiveAPI implementation, and depends on: EABase, EAThread.
2024-04-05 18:29:03 +02:00

247 lines
8.1 KiB
C

/*H*************************************************************************************************/
/*!
\File dirtynames.c
\Description
This module provides helper functions for manipulating persona and master
account name strings.
\Notes
None.
\Copyright
Copyright (c) Tiburon Entertainment / Electronic Arts 2002-2003. ALL RIGHTS RESERVED.
\Version 1.0 12/10/02 (DBO) First Version
*/
/*************************************************************************************************H*/
/*** Include files *********************************************************************/
#include <stdio.h>
#include "DirtySDK/platform.h"
#include "DirtySDK/dirtysock/dirtynames.h"
/*** Defines ***************************************************************************/
#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif
/*** Macros ****************************************************************************/
/*** Type Definitions ******************************************************************/
/*** Function Prototypes ***************************************************************/
/*** Variables *************************************************************************/
// Private variables
static const unsigned char xlat[256] ={
0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
};
// Public variables
/*** Private Functions *****************************************************************/
/*F************************************************************************************************/
/*!
\Function toXlatIndex
\Description
Converts a char to xlat table index using its ascii char representation.
Characters outside the range [0, 255] are treated as 255.
\Input str - Input char
\Output xlat index - int32_t (0 to 255)
*/
/************************************************************************************************F*/
int32_t toXlatIndex(const char str)
{
int32_t xlatIndex = (int32_t)str;
return (xlatIndex >= 0 && xlatIndex < 256) ? xlatIndex : 255;
}
/*** Public Functions ******************************************************************/
/*F************************************************************************************************/
/*!
\Function DirtyUsernameCompare
\Description
Compare two master account names. Ignore case and non-printable ascii characters.
\Input pName1 - Input account name 1
\Input pName2 - Input account name 2
\Output int32_t - < 0 = pName1 < pName2
= 0 = pName1 = pName2
> 0 = pName1 > pName2
\Version 1.0 05/01/2003 (DBO) Taken from LobbyHasher (HashStrCmp)
*/
/************************************************************************************************F*/
int32_t DirtyUsernameCompare(const char *pName1, const char *pName2)
{
int32_t iCmp;
unsigned char cCh1, cCh2;
// compare the strings
do {
// grab the data
while ((cCh1 = xlat[toXlatIndex(*pName1++)]) == 1)
;
while ((cCh2 = xlat[toXlatIndex(*pName2++)]) == 1)
;
// see if different
if ((iCmp = cCh1-cCh2) != 0)
return(iCmp);
} while (cCh1 != 0);
// they are the same
return(0);
}
/*F************************************************************************************************/
/*!
\Function DirtyUsernameSubstr
\Description
Determine if pMatch is a substring of pSrc. Ignore case and non-printable ascii characters.
\Input pSrc - Location to store converted name
\Input pMatch - Input account name
\Output int32_t - TRUE if pMatch is a substring of pSrc; FALSE otherwise
\Version 1.0 05/02/2003 (DBO) Initial version.
*/
/************************************************************************************************F*/
int32_t DirtyUsernameSubstr ( const char *pSrc, const char *pMatch )
{
int32_t iSrcIdx;
int32_t iMatchIdx1;
int32_t iMatchIdx2;
char cCh1;
char cCh2;
if ( (pMatch == NULL) || (pMatch[0] == '\0') )
return(TRUE);
if ( (pSrc == NULL) || (pSrc[0] == '\0') )
return(FALSE);
for(iSrcIdx = 0; pSrc[iSrcIdx] != '\0'; iSrcIdx++)
{
iMatchIdx1 = iSrcIdx;
iMatchIdx2 = 0;
do
{
// Skip over ignored characters
while ( (cCh1 = xlat[toXlatIndex(pSrc[iMatchIdx1++])]) == 1 )
;
while ( (cCh2 = xlat[toXlatIndex(pMatch[iMatchIdx2++])]) == 1 )
;
if ( cCh2 == 0 )
return(TRUE);
}
while ( (cCh1 != 0) && (cCh1 == cCh2) );
}
return(FALSE);
}
/*F************************************************************************************************/
/*!
\Function DirtyNameCreateCanonical
\Description
Create the canonical form of the given name. This essentially lowercases the name and
strips non-printable ascii characters as per the xlat table.
\Input pName - The input name to create the canonical name from.
\Input pCanonical - The buffer to output the canonical name into
\Input uLen - The length of pCanonical
\Output int32_t - 0 on success; -1 if the output buffer is too small
*/
/************************************************************************************************F*/
int32_t DirtyNameCreateCanonical(const char *pName, char * pCanonical, size_t uLen)
{
unsigned char cCh;
while (uLen > 0)
{
// Strip the ignored characters
while ((cCh = xlat[toXlatIndex(*pName++)]) == 1)
;
if ((cCh >= 'A') && (cCh <= 'Z'))
cCh |= 32;
*pCanonical++ = cCh;
uLen--;
if (cCh == 0)
return 0;
}
return -1;
}
/*F************************************************************************************************/
/*!
\Function DirtyUsernameHash
\Description
Generate the hash code for the given persona name. This hashing function will hash the
canonical form of the name rather than the raw bytes to ensure that equivalent names
always hash to the same value, as per the xlat table.
\Input pName - The input name to generate a hash code.
\Output uint32_t - The generated hash code.
*/
/************************************************************************************************F*/
uint32_t DirtyUsernameHash(const char *pName)
{
unsigned char cCh;
uint32_t result = 2166136261U; // FNV1 hash. Perhaps the best string hash.
do
{
// Strip the ignored characters
while ((cCh = xlat[toXlatIndex(*pName++)]) == 1)
;
result = (result * 16777619) ^ cCh;
} while (cCh != 0);
return result;
}