PDA

View Full Version : Custom Bad Word Filter


Bardalicious
05-08-2014, 05:47 PM
Out of curiousity, has anyone looked into where the trigger words are stored for the bad word filter option? I'm just wondering if there is an editable list that can be added or subtracted from somewhere in the local client files.

Telin
05-08-2014, 06:01 PM
I've seen them inside the eqgame.exe at some point. It was a shock to see them at first.

no chewie dont
05-08-2014, 06:09 PM
I've seen them inside the eqgame.exe at some point. It was a shock to see them at first.

hahha this sounds great, were they comma separated or one per line or what? i wanna imagine this correctly

Telin
05-08-2014, 06:12 PM
Yes every bad word imaginable separated by periods. I thought it was some crazy rant inside at first until I remembered the word filter.

a_gnoll_pup
05-08-2014, 08:01 PM
Some of the cool bad words in the filter:

aeiouy more better best him his of that were has was are and the do to did go went it its it's them they'll we'll let's me my I'

This isn't actually in the badword filter, but it will replace words at random in your speech for some retarded reason.

Here's the function governing it:

char __cdecl SpeakBabel(const char *Source, char *Dest, int a3, unsigned __int8 a4, int a5)
{
const char *v5; // ebx@1
size_t v6; // eax@1
size_t v7; // edx@1
char *v8; // edi@10
char *v9; // ebx@11
char v10; // cl@14
signed int v11; // eax@14
int v12; // esi@18
size_t v13; // eax@22
signed int v14; // esi@24
size_t v15; // edi@25
unsigned __int8 v16; // bl@34
size_t v17; // eax@72
int v18; // edi@73
char *v19; // esi@74
unsigned __int8 v20; // al@76
char v21; // dl@87
int v22; // esi@98
int v23; // eax@100
int *v24; // esi@100
char *v26; // [sp-8h] [bp-202Ch]@33
const char *v27; // [sp-4h] [bp-2028h]@33
const char *v28; // [sp-4h] [bp-2028h]@39
char Str; // [sp+Ch] [bp-2018h]@21
char C[4096]; // [sp+100Ch] [bp-1018h]@9
int v31; // [sp+200Ch] [bp-18h]@72
int v32; // [sp+2010h] [bp-14h]@10
char Str1[16]; // [sp+2014h] [bp-10h]@22

v5 = Source;
v6 = strlen(Source);
v7 = 0;
if ( Dest && Source )
{
if ( a4 > 0x63u && a5 )
{
LOBYTE(v6) = (unsigned int)strcpy(Dest, Source);
return v6;
}
*Dest = 0;
if ( (signed int)v6 > 4095 )
v6 = 4095;
if ( (signed int)v6 > 0 )
{
v7 = v6;
memcpy(C, Source, v6);
}
C[v7] = 0;
v8 = C;
v32 = (int)C;
if ( strlen(C) )
{
v9 = Dest;
while ( 1 )
{
if ( *v8 == 18 )
{
v10 = v8[1];
v11 = 1;
while ( v10 && v10 != 18 )
v10 = v8[v11++ + 1];
v12 = (int)&v8[v11];
if ( v8[v11] == 18 )
{
strncat(v9, v8, v11 + 1);
strcat(v9, " ");
v32 = v12 + 1;
}
else
{
*v8 = 81;
}
goto LABEL_96;
}
v32 = CEverQuest::GrabFirstWord(v8, &Str);
if ( strlen(&Str) )
{
nullterminated_strncpy(Str1, &Str, 0x10u);
}
else
{
nullterminated_strncpy(Str1, (char *)v32, 0x10u);
v13 = strlen(Str1);
v32 += v13;
}
v14 = 0;
if ( !a5 )
{
v15 = strlen(Str1);
if ( (signed int)v15 > 0 )
{
if ( BadWord(Str1, v15) )
{
if ( (signed int)v15 > 0 )
{
do
Str1[v14++] = RandNbr() % 26 + 96;
while ( v14 < (signed int)v15 );
}
if ( strlen(v9) )
strcat(v9, Str1);
else
strcpy(v9, Str1);
if ( v9[strlen(v9) - 1] != 32 )
{
v27 = " ";
v26 = Dest;
LABEL_95:
strcat(v26, v27);
goto LABEL_96;
}
goto LABEL_96;
}
}
}
v16 = number_percent();
if ( v16 > a4 && (signed int)strlen(Str1) < 8 )
{
if ( !_stricmp(Str1, "I") || !_stricmp(Str1, "I'") || !_stricmp(Str1, "my") )
{
v28 = "me";
LABEL_71:
strcpy(Str1, v28);
goto LABEL_72;
}
if ( !_stricmp(Str1, "let's") || !_stricmp(Str1, "we'll") )
{
v28 = (const char *)&unk_5BED3C;
goto LABEL_71;
}
if ( !_stricmp(Str1, "they'll") )
{
v28 = "them";
goto LABEL_71;
}
if ( !_stricmp(Str1, "it's") || !_stricmp(Str1, off_5BEFF0) )
{
v28 = "it";
goto LABEL_71;
}
if ( !_stricmp(Str1, "went") )
{
v28 = "did go";
goto LABEL_71;
}
if ( !_stricmp(Str1, "a")
|| !_stricmp(Str1, "am")
|| !_stricmp(Str1, "an")
|| !_stricmp(Str1, "to")
|| !_stricmp(Str1, "or")
|| !_stricmp(Str1, "do")
|| !_stricmp(Str1, off_5BEFD0)
|| !_stricmp(Str1, off_5BEFCC)
|| !_stricmp(Str1, _string_)
|| !_stricmp(Str1, off_5BEFC4)
|| !_stricmp(Str1, off_5BEFC0)
|| !_stricmp(Str1, "were")
|| !_stricmp(Str1, "that") )
{
LABEL_66:
v28 = byte_5DF120;
goto LABEL_71;
}
if ( v16 - a4 > 20 )
{
if ( !_stricmp(Str1, "of") || !_stricmp(Str1, "is") )
goto LABEL_66;
if ( !_stricmp(Str1, off_5BEFA8) )
{
v28 = (const char *)&off_5BEFA4;
goto LABEL_71;
}
if ( !_stricmp(Str1, "best") )
{
v28 = "more better";
goto LABEL_71;
}
}
}
LABEL_72:
v17 = strlen(Str1);
v31 = v17;
if ( (signed int)v17 > 0 )
{
v18 = 0;
if ( (signed int)v17 > 0 )
{
do
{
v19 = &Str1[v18];
if ( isalpha((unsigned __int8)Str1[v18]) )
{
if ( number_percent() > 40 )
{
v20 = number_percent();
if ( v20 > 5u )
{
if ( v20 > a4 + 10 )
{
if ( v20 <= 0x62u || v18 <= 0 || *((_BYTE *)&v32 + v18 + 3) == 32 || v19[1] == 32 )
{
if ( v20 - a4 <= 30 )
{
if ( IsVowel(*v19) )
{
*v19 = ReturnRandomVowel();
}
else
{
do
{
v21 = RandNbr() % 25 + 97;
*v19 = v21;
}
while ( IsVowel(v21) );
}
}
else
{
*v19 = RandNbr() % 26 + 96;
}
}
else
{
*v19 = 32;
}
}
}
}
}
++v18;
}
while ( v18 < v31 );
}
if ( strlen(Str1) )
{
if ( strlen(Dest) )
strcat(Dest, Str1);
else
strcpy(Dest, Str1);
if ( Dest[strlen(Dest) - 1] != 32 )
{
v27 = " ";
v26 = Dest;
goto LABEL_95;
}
}
}
LABEL_96:
if ( !strlen((const char *)v32) )
{
v5 = Source;
break;
}
v9 = Dest;
v8 = (char *)v32;
}
}
v6 = strlen(v5);
v22 = v6 - 1;
if ( (signed int)(v6 - 1) > 0 )
{
v6 = strlen(Dest);
if ( v6 )
{
v23 = (unsigned __int8)v5[v22];
v24 = (int *)&v5[v22];
if ( !isalpha(v23) && !isdigit(*(_BYTE *)v24) )
Dest[strlen(Dest) - 2] = *(_BYTE *)v24;
Dest[strlen(Dest) - 1] = 0;
LOBYTE(v6) = *Dest;
if ( *Dest >= 97 && (char)v6 <= 122 )
LOBYTE(v6) = v6 - 32;
*Dest = v6;
}
}
}
return v6;
}

Ironically no one ever caught the bug/mishap until 2006 when SOE fixed it. I assume all the developers just thought people were retarded and never thought that kind of code could exist.

r00t
05-08-2014, 08:47 PM
Secrets do you know if that has anything to do with, like if you're not 100 in Common (like Ogres), it'll change your I's to Me's


http://i.imgur.com/SaMNDjP.png

a_gnoll_pup
05-08-2014, 09:16 PM
Secrets do you know if that has anything to do with, like if you're not 100 in Common (like Ogres), it'll change your I's to Me's


http://i.imgur.com/SaMNDjP.png

As far as I know it does, but i've seen it happen even with maxed common tongue interestingly enough

SamwiseRed
05-08-2014, 10:47 PM
secrets and naez, a powerful duo. too much power imo

Bardalicious
05-08-2014, 10:58 PM
inc rogean antihax ban on all my accounts for customizing the filter

r00t
05-08-2014, 11:11 PM
You could edit over some of those with a hex editor to get custom behavior. It would change the crc checksum for the .exe though. iirc the client sends a checksum for both the spellfile and the eqgame.exe, so you might not be able to get past p99's char select checks

Bardalicious
05-08-2014, 11:13 PM
You could edit over some of those with a hex editor to get custom behavior. It would change the crc checksum for the .exe though. iirc the server sends a checksum for both the spellfile and the eqgame.exe, so you might not be able to get past p99's char select checks

crc checksums are incredibly easy to spoof though

Bardalicious
05-08-2014, 11:13 PM
NOT THAT I'D EVER DO THAT SORT OF THING MIND YOU

r00t
05-08-2014, 11:17 PM
client* sry, and yea I bet the collision rate is pretty high but still difficult to perfect