Another possible fix would be to add code to
bool CCharServer::pakRequestWorld( CCharClient* thisclient, CPacket* P )The 715 packet comes in with two pieces of information
a Byte ( btCharNO )containing the index value of the selected avatar
the String containing the character's name
It should be pretty easy to add a simple query to return all the names of characters owned by the player and then check the name of the one at position btCharNO
If it doesn't equal the name in the packet then you have a cheater
Alternatively we could just ignore the name sent in by the client and simply load the character at that index value.
I have modified the source in the project 137 repo as follows
- // Send away the world IP
- bool CCharServer::pakRequestWorld( CCharClient* thisclient, CPacket* P )
- {
- if (!thisclient->isLoggedIn) return false;
- MYSQL_ROW row;
- MYSQL_RES *result;
- memset( &thisclient->charname, '\0', 17 );
- memcpy( thisclient->charname, &P->Buffer[3], (P->Size-6-4)>16?16:(P->Size-6-4) );
-
- //PY Added code to validate character names sent in from client
- unsigned int charnum = 0;
- CCharacter chars[5];
- int btCharNO = P->Buffer[0];
- result = DB->QStore("SELECT char_name FROM characters WHERE account_name='%s'", thisclient->username);
- if(result==NULL) return false;
- while (row = mysql_fetch_row(result))
- {
- memset( &chars[charnum].char_name, '\0', 17 );
- strcpy( chars[charnum].char_name , row[0] );
- charnum++;
- }
- Log(MSG_WARNING,"Characters in this account %s, %s, %s, %s, %s",chars[0].char_name, chars[1].char_name, chars[2].char_name, chars[3].char_name, chars[4].char_name); //displays all charcters in account
- Log(MSG_WARNING,"Selected Character from client %s",chars[btCharNO].char_name); //displays character name sent in from the client on the 0x0715 packet
- if ( strcmp(thisclient->charname, chars[btCharNO].char_name) != 0 )
- {
- Log(MSG_WARNING,"Selected Character is invalid. Hack detected"); //they don't match
- thisclient->accesslevel = -1;
- DB->QExecute( "UPDATE accounts SET accesslevel='0' WHERE id=%i", thisclient->userid); //ban the player
- thisclient->isActive = false;
- return false;
- }
- //PY anti-hack end
-
-
- if(!CheckEscapeMySQL(thisclient->charname,17,true))
- {
- Log(MSG_WARNING,"A charname contains incorrect caracters or incorrect size (see warnings above)");
- return false;
- }
-
- DB->QFree( );
Could probably be simplified a little but whatever.
Tested and working with valid characters.
Not tested with actual hack attempts
Need to lookup information on NARose items, skills, quests?
Now featuring a newly completed skill tree for all classesFormatting fixed for different resolutions"A Gazelle is nothing but a giraffe plotted logarithmicaly"