示例#1
0
// Messenger actions (add/remove/invite)
bool CCharServer::pakMessengerManager ( CCharClient* thisclient, CPacket* P )
{
    BYTE action = GETBYTE((*P),0);
    switch (action)
    {
        case 0x01://wanna be my friend?
        {
            char* nick = new (nothrow) char[P->Size-7];
            if(nick==NULL)
            {
                Log(MSG_ERROR, "Error allocing memory: pakMessengerManager 1" );
                return false;
            }

            memcpy( nick, &P->Buffer[1], P->Size-7 );
            Log(MSG_INFO,"%s Trying to invite %s",nick,thisclient->charname);

            CCharClient* otherclient = (CCharClient*) GetClientByName (nick);
            if(otherclient!=NULL)
            {//Send friend invitation  (check this one)
                BEGINPACKET( pak, 0x7e1 );
                ADDBYTE    ( pak, 0x01 );
                ADDWORD    ( pak, 0x0000 );
                ADDSTRING  ( pak, thisclient->charname );
                ADDBYTE    ( pak, 0x00 );
                otherclient->SendPacket(&pak);
                Log(MSG_INFO,"%s exists, invite sent to %s",nick,otherclient->charname);
            }
            else
            {//This charname doesnt exist
               BEGINPACKET( pak, 0x7e1 );
               ADDBYTE    ( pak, 0x04 );
               ADDSTRING  ( pak, nick );
               ADDBYTE    ( pak, 0x00 );
               thisclient->SendPacket(&pak);
               Log(MSG_INFO,"invite: %s doesn't exist",nick);
            }
            delete []nick;
        }
        break;
        case 0x02://yes i want
        {
            char* nick = new (nothrow) char[P->Size-9];
            if(nick==NULL)
            {
                Log(MSG_ERROR, "Error allocing memory: pakMessengerManager 2" );
                return false;
            }
            memcpy( nick, &P->Buffer[3], P->Size-9 );

            if(!CheckEscapeMySQL(nick,-1,true))
            {
                Log(MSG_WARNING,"A nick (friendlist) contains incorrect caracter (see warnings above)");
                return false;
            }

            CCharClient* otherclient = (CCharClient*) GetClientByName (nick);
            if(otherclient!=NULL)
            {
                BEGINPACKET( pak, 0x7e1 );
                ADDBYTE    ( pak, 0x02 );
                /*ADDWORD    ( pak, thisclient->charid );
                ADDBYTE    ( pak, 0x00 );
                ADDWORD    ( pak, 0x0000 );*/
                ADDDWORD    ( pak, thisclient->charid );
                ADDBYTE    ( pak, 0x00 );
                ADDSTRING  ( pak, thisclient->charname );
                ADDBYTE    ( pak, 0x00);
                otherclient->SendPacket(&pak);

                //Add friend to my friend list(sql)
                if(!DB->QExecute("INSERT INTO list_friend (id,idfriend,namefriend) VALUES (%i,%i,'%s')",otherclient->charid,thisclient->charid,thisclient->charname))
                {
                    Log(MSG_WARNING,"error addind %s to %s friend list",otherclient->charname,thisclient->charname);
                    return false;
                }

                CFriendList * newfriend1 = new (nothrow) CFriendList;
                if(newfriend1==NULL)
                    return false;

                newfriend1->id = otherclient->charid; //friendid
                strcpy(newfriend1->name, otherclient->charname); //friend name

                thisclient->FriendList.push_back( newfriend1 );
                RESETPACKET( pak, 0x7e1 );
                ADDBYTE    ( pak, 0x02 );
                /*ADDWORD    ( pak, otherclient->charid );
                ADDBYTE    ( pak, 0x00 );
                ADDWORD    ( pak, 0x0000 );*/
                ADDDWORD    ( pak, otherclient->charid );
                ADDBYTE    ( pak, 0x00 );
                ADDSTRING  ( pak, otherclient->charname );
                ADDBYTE    ( pak, 0x00);
                thisclient->SendPacket(&pak);

                //Add me to his friend list (sql)
                if(!DB->QExecute("INSERT INTO list_friend (id,idfriend,namefriend) VALUES (%i,%i,'%s')",thisclient->charid,otherclient->charid,otherclient->charname))
                    return false;
                CFriendList * newfriend2 = new (nothrow) CFriendList;
                if(newfriend2==NULL)
                    return false;
                newfriend2->id = thisclient->charid; //friendid
                strcpy(newfriend2->name, thisclient->charname); //friend name
                otherclient->FriendList.push_back( newfriend2 );
                Log(MSG_INFO,"accept %s ok",nick);
            }
            else//not found
            {
               BEGINPACKET( pak, 0x7e1 );
               ADDBYTE    ( pak, 0x04 );
               ADDSTRING  ( pak, nick );
               ADDBYTE    ( pak, 0x00 );
               thisclient->SendPacket(&pak);
               Log(MSG_INFO,"accept: %s doesn't exist",nick);
            }
            delete []nick;
        }
        break;
        case 0x03://no, i dont want
        {
            char* nick = new (nothrow) char[P->Size-9];
            if(nick==NULL)
            {
                Log(MSG_ERROR, "Error allocing memory: pakMessengerManager 3" );
                return false;
            }
            memcpy( nick, &P->Buffer[3], P->Size-9 );
            CCharClient* otherclient = (CCharClient*) GetClientByName (nick);
            if(otherclient!=NULL)
            {
                BEGINPACKET( pak, 0x7e1 );
                ADDBYTE    ( pak, 0x03 );
                ADDSTRING  ( pak, thisclient->charname );
                ADDBYTE    ( pak, 0x00);
                otherclient->SendPacket(&pak);
                Log(MSG_INFO,"refuse: %s ok",nick);
            }
            else
            {
               BEGINPACKET( pak, 0x7e1 );
               ADDBYTE    ( pak, 0x04 );
               ADDWORD    ( pak, 0x0000 );
               ADDSTRING  ( pak, nick );
               ADDBYTE    ( pak, 0x00 );
               thisclient->SendPacket(&pak);
               Log(MSG_INFO,"refuse: %s doesn't exist",nick);
            }
        }
        break;
        case 0x05://delete user.
        {
            //WORD id = GETWORD ((*P),1);
            DWORD id = GETDWORD ((*P),1);
            if(!DB->QExecute("DELETE FROM list_friend WHERE id=%i and idfriend=%i",thisclient->charid,id))
            {
                Log(MSG_INFO,"user failed to delete friend slot %i",thisclient->charname,id);
                return false;
            }

            Log(MSG_INFO,"user %s deletes friend slot %i",thisclient->charname,id);

            CCharClient* otherclient = (CCharClient*) GetClientByID(id);
            if(otherclient!=NULL)
            {
                    ChangeMessengerStatus ( thisclient, otherclient, 0x08);
            }
        }
        break;
        case 0xfa://messenger logout
        {
            //WORD id = GETWORD ((*P),1);
            DWORD id = GETDWORD ((*P),1);
            CCharClient* ctherclient = (CCharClient*) GetClientByID(id);
            if(ctherclient==NULL)
                return true;
            ctherclient->logout = true;
            for(UINT i=0;i<ctherclient->FriendList.size();i++)
            {
                CFriendList* thisfriend = ctherclient->FriendList.at( i );
                CCharClient* otherclient = (CCharClient*) GetClientByID( thisfriend->id );
                if(otherclient!=NULL)
                {
                    ChangeMessengerStatus ( ctherclient, otherclient, 0x08);
                }
            }
           //Logout in clan
           ClanLogout ( ctherclient );
        }
        break;
        default:
            Log( MSG_INFO, "Friend action unknown: %i", action );
        break;
    }
    return true;
}
示例#2
0
// 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) );

    if(!CheckEscapeMySQL(thisclient->charname,17,true))
    {
        Log(MSG_WARNING,"A charname contains incorrect caracters or incorrect size (see warnings above)");
        return false;
    }

	Log( MSG_INFO,"User %s(%i) selected char '%s'", thisclient->username, thisclient->userid, thisclient->charname);
	if(!DB->QExecute("UPDATE accounts SET lastchar='%s' WHERE id=%i", thisclient->charname, thisclient->userid))
	   return false;
	result = DB->QStore("SELECT host,port,lanip,lansubmask FROM channels WHERE id=%u and owner=%u and type=2", thisclient->channel, Config.ServerID);
	if(result==NULL) return false;
	if(mysql_num_rows( result )!=1 )
	{
        Log( MSG_WARNING, "Invalid Server: %i", thisclient->channel );
        DB->QFree( );
	    return false;
    }
	row = mysql_fetch_row( result );
	BEGINPACKET( pak, 0x711 );
	ADDWORD    ( pak, atoi(row[1]) );                // PORT
	ADDDWORD   ( pak, thisclient->userid );
	ADDDWORD   ( pak, 0x87654321 );

	if(strcmp(thisclient->ClientSubNet,row[3])==0)//from lan
	{
        ADDSTRING( pak, row[2] );
       	Log(MSG_INFO, "Sending LanIP" );
    }
    else if(strcmp( thisclient->ClientSubNet ,"127.0.0")==0)//same computer
    {
        ADDSTRING( pak, "127.0.0.1" );
       	Log(MSG_INFO, "Sending Localhost IP" );
    }
    else
    {
        ADDSTRING( pak, row[0] );
       	Log(MSG_INFO, "Sending InetIP");
    }
	ADDBYTE    ( pak, 0 );
	thisclient->SendPacket( &pak );
	DB->QFree( );
    //CHAR INFORMATION        0       1    2    3      4
	result = DB->QStore("SELECT clanid,clan_rank,id,level,classid,rewardpoints FROM characters WHERE char_name='%s'", thisclient->charname);
	if(result==NULL) return false;
	if(mysql_num_rows(result)!=1)
	{
        Log( MSG_WARNING, "Number of user with charname '%s' is %i", thisclient->charname,mysql_num_rows(result));
        DB->QFree( );
        return false;
    }
	row = mysql_fetch_row( result );
	thisclient->clanid =  atoi( row[0] );
	thisclient->clan_rank = atoi( row[1] );
	thisclient->charid = atoi( row[2] );
	thisclient->level = atoi( row[3] );
	thisclient->job = atoi( row[4] );
    thisclient->reward_points=atoi( row[5] );  //LMA: reward points:
	DB->QFree( );
//MESSENGER INFORMATION
//              //          0        1
	result = DB->QStore("SELECT idfriend,namefriend FROM list_friend WHERE id=%i", thisclient->charid);
	if(result==NULL) return false;
	BYTE nfriends = mysql_num_rows(result) & 0xff;

	RESETPACKET( pak, 0x7e1 );// Friend list command
    ADDBYTE    ( pak, 0x06 );// Sending Friend List
    ADDBYTE    ( pak, nfriends );// # friends
	while(row = mysql_fetch_row( result ))
	{
        CFriendList * newfriend = new CFriendList;
        assert(newfriend);
        newfriend->id = atoi(row[0]); //friendid
        strcpy(newfriend->name, row[1]); //friend name
        thisclient->FriendList.push_back( newfriend );
        ADDWORD    (pak, newfriend->id);// friend id
        ADDWORD    (pak, 0x0000 );
        CCharClient* otherclient = (CCharClient*) GetClientByID( newfriend->id );
        if(otherclient!=NULL) //is online??
        {
            ADDBYTE    (pak, 0x07 );   //online
            ChangeMessengerStatus ( thisclient, otherclient, 0x07);
        }
        else
        {
            ADDBYTE    (pak, 0x08 );//offline
        }
        ADDSTRING  (pak, newfriend->name); //friend name
        ADDBYTE    (pak, 0x00 );
    }
    thisclient->SendPacket( &pak );
	DB->QFree( );
    thisclient->logout = false;

    //SEND CLAN INFORMATION
    SendClanInfo (thisclient);

    return true;
}
示例#3
0
// delete/resurect character
bool CCharServer::pakDeleteChar( CCharClient* thisclient, CPacket* P )
{
	if(!thisclient->isLoggedIn) return false;
	char* name = (char*)&P->Buffer[2];

    if(!CheckEscapeMySQL(name,-1,true))
    {
        Log(MSG_WARNING,"A name (delete / resurrect) contains incorrect caracter (see warnings above)");
        return false;
    }

    MYSQL_RES *result;
	MYSQL_ROW row;
	result = DB->QStore("SELECT account_name FROM characters WHERE char_name='%s' LIMIT 1", name);
	if(result==NULL) return false;
	row = mysql_fetch_row(result);

	//LMA: no case.
	//if (strcmp(row[0], thisclient->username)!=0)
	if (stricmp(row[0], thisclient->username)!=0)
	{
	    Log(MSG_HACK, "User %s tried deleting another users (%s) character.", thisclient->username, name);
	    DB->QFree( );
	    return false;
	}
	DB->QFree( );
    short int action = GETBYTE((*P), 1 );
    unsigned long int DeleteTime = 0;
    switch(action)
    {
        case 0x00://Resurrect
        {
            DeleteTime = 0;
            //if(!DB->QExecute(" UPDATE characters SET deletetime=0 WHERE char_name='%s'",(char*)&P->Buffer[2] ))
            if(!DB->QExecute(" UPDATE characters SET deletetime=0 WHERE char_name='%s'",name))
            {
                return false;
            }

        }
        break;
        case 0x01://Delete
        {
            DeleteTime = GetServerTime( ) + Config.DeleteTime;
            //if(!DB->QExecute(" UPDATE characters SET deletetime=%i WHERE char_name='%s'",DeleteTime, (char*)&P->Buffer[2] ))
            if(!DB->QExecute(" UPDATE characters SET deletetime=%i WHERE char_name='%s'",DeleteTime,name))
            {
                return false;
            }

        }
        break;
    }
    BEGINPACKET( pak, 0x714 );
    if(DeleteTime > 0 )
    {
        ADDDWORD   ( pak, Config.DeleteTime );
    }
    else
    {
        ADDDWORD   ( pak, 0x00000000 );
    }
    ADDSTRING  ( pak, (char*)&P->Buffer[2] );
    ADDBYTE    ( pak, 0x00 );
    thisclient->SendPacket( &pak );
    return true;
}
示例#4
0
// Do player identification
bool CCharServer::pakDoIdentify( CCharClient* thisclient, CPacket* P )
{
	if (thisclient->isLoggedIn) return false;
	MYSQL_RES *result;
	MYSQL_ROW row;
	thisclient->userid = GETDWORD((*P), 0x00);
	memcpy( thisclient->password, &P->Buffer[4], 32 );

	//LMA: checking is password is ok.
	if(!CheckEscapeMySQL(thisclient->password,33,true))
	{
	    Log(MSG_WARNING,"A password contains incorrect caracters or is too long (see warnings above)");
	    return false;
	}

	result = DB->QStore("SELECT username,lastsvr,accesslevel,platinum FROM accounts WHERE id=%i AND password='******'", thisclient->userid, thisclient->password);
	if(result==NULL) return false;
	if (mysql_num_rows( result ) != 1)
    {
		Log( MSG_HACK, "Someone tried to connect to char server with an invalid account" );
		DB->QFree( );
		return false;
	}
    else
    {
		row = mysql_fetch_row(result);
		strncpy(thisclient->username, row[0],16);
		thisclient->channel = atoi(row[1]);
		thisclient->accesslevel = atoi(row[2]);
		thisclient->platinum = atoi(row[3]);
		DB->QFree( );

        if(!CheckEscapeMySQL(thisclient->username,-1,true))
        {
            Log(MSG_WARNING,"A username contains incorrect caracters (see warnings above)");
            return false;
        }

	}

	//LMA: Adding a log for admins. Account ids shouldn't be less than 78
	if(thisclient->userid<78)
	{
	    Log(MSG_INFO,"Account ID %i (%s) is < 78, this is NOT advised to have ids too low (<10). You should change the id if it is the case.",thisclient->userid,thisclient->username);
	}

	//LMA: We try something here... We tell the worldserver to disconnect every character
	//from this account to avoid multi client on the same account (let's call this a preemptive strike).
    if(GetNbUserID(thisclient->userid)>1)
    {
        Log(MSG_HACK,"[HACK] User ID %u (%s) has several avatars logged on the same account.",thisclient->userid,thisclient->username);
        return false;
    }

	Log( MSG_INFO,"User '%s'(#%i) logged in", thisclient->username, thisclient->userid );

	BEGINPACKET( pak, 0x070c );
	ADDBYTE    ( pak, 0 );
	ADDDWORD   ( pak, 0x87654321);
	ADDDWORD   ( pak, 0x00000000 );
	thisclient->SendPacket( &pak );
	result = DB->QStore( "SELECT online FROM accounts WHERE username='******'", thisclient->username );
    if(result==NULL) return false;
    row = mysql_fetch_row(result);
    bool online = atoi(row[0]);
    DB->QFree( );
    if(online)
        return false;
    if(!DB->QExecute( "UPDATE accounts SET online=1 WHERE username='******'", thisclient->username ))
        return false;
	thisclient->isLoggedIn = true;
    return true;
}
示例#5
0
// Create a new clan
bool CWorldServer::pakCreateClan ( CPlayer* thisclient, CPacket* P )
{
    if(thisclient->CharInfo->Zulies < 1000000)
        return true;

    thisclient->CharInfo->Zulies -= 1000000;
	//MYSQL_ROW row;
    int background = GETWORD((*P),1);
    int icon = GETWORD((*P),3);
    char*name=(char*)&P->Buffer[5];
    char*slogan=(char*)&P->Buffer[strlen(name)+6];

    //LMA: Check if name already exists and is short enough.
    if(!CheckValidName(thisclient,name))
    {
        return true;
    }

    //LMA: Checking if it needs to be escaped.
    if(!CheckEscapeMySQL(name,50,true))
    {
        return true;
    }

    //LMA: checking if the name is ok.
	MYSQL_RES *result = DB->QStore("SELECT name FROM list_clan WHERE name='%s'", name);
    if(result==NULL) return true;
	if ( mysql_num_rows( result ) > 0 )
    {
        BEGINPACKET( pak, 0x07e0 );
	    ADDWORD    ( pak, 0x42 );
		thisclient->client->SendPacket( &pak );
		DB->QFree( );
		return true;
	}
    DB->QFree( );

    //Check if user can create a clan
    if( thisclient->Clan->clanid != 0 )
    {
        BEGINPACKET( pak, 0x7e0 );
	    ADDWORD    ( pak, 0x44 );
		thisclient->client->SendPacket( &pak );
		return true;
	}

    char * lma_slogan = new char[strlen(slogan) + 1];
	strcpy(lma_slogan,slogan);
	char * new_slogan = new char[strlen(lma_slogan)*3 +1];
	mysql_real_escape_string(DB->Mysql, new_slogan,lma_slogan,strlen(lma_slogan));
	//mysql_real_escape_string(DB->Mysql, new_slogan,"abcdefghijk",11);
    Log(MSG_INFO,"[WS] New clan %s created, slogan detected=%s, cleaned=%s ",name,slogan,new_slogan);

    //LMA: checking slogan's size.
    if(strlen(new_slogan)>=100)
    {
        Log(MSG_HACK,"%s tried to create clan %s with too long slogan %s (%i>=100)",thisclient->CharInfo->charname,name,new_slogan,strlen(new_slogan));
        return true;
    }

    DB->QExecute( "INSERT into list_clan (logo,back,name,cp,grade,slogan,news) values (%i,%i,'%s',0,1,'%s','')",icon,background,name,new_slogan);
	thisclient->Clan->clanid = mysql_insert_id(DB->Mysql);
	thisclient->Clan->clanrank = 6;
    thisclient->Clan->logo = icon;
    thisclient->Clan->back = background;
    strncpy(thisclient->Clan->clanname,name,16);
    thisclient->Clan->grade = 1;

    //Update user clan information
    DB->QExecute( "UPDATE characters set clanid=%i,clan_rank=6 where id=%i",
                                    thisclient->Clan->clanid,thisclient->CharInfo->charid);
    //load clan info in char server
	BEGINPACKET( pak, 0x7e0 );
	ADDBYTE    ( pak, 0xfa ); //action to update clan informacion (charserver)
	ADDWORD    ( pak, thisclient->Clan->clanid );
	//ADDWORD    ( pak, thisclient->CharInfo->charid );
	ADDDWORD    ( pak, thisclient->CharInfo->charid );
	ADDWORD    ( pak, thisclient->clientid );
	cryptPacket( (char*)&pak, cct );
	send( csock, (char*)&pak, pak.Size, 0 );

    //Send to other players
    RESETPACKET( pak, 0x7e0 );
    ADDBYTE    ( pak, 0x35 );
    ADDWORD    ( pak, thisclient->clientid );
    ADDDWORD    ( pak, thisclient->Clan->clanid );//clanid
    ADDWORD    ( pak, thisclient->Clan->back );
    ADDWORD    ( pak, thisclient->Clan->logo );
    ADDBYTE    ( pak, thisclient->Clan->grade );//clan grade
    ADDBYTE    ( pak, thisclient->Clan->clanrank );//clan rank
    ADDSTRING  ( pak, thisclient->Clan->clanname );
    ADDBYTE    ( pak, 0x00 );
    SendToVisible( &pak, thisclient );

    delete[] lma_slogan;
	delete[] new_slogan;

    return true;
}