/*
 * Irresistible Gaming (c) 2018
 * Developed by Lorenc
 * Module: cnr\auth\account.pwn
 * Purpose: module associated with account components (login, register)
 */

/* ** Includes ** */
#include 							< YSI\y_hooks >

/* ** Variables ** */
new
    bool: p_PlayerLogged    		[ MAX_PLAYERS char ],
    p_AccountID						[ MAX_PLAYERS ]
;

/* ** Hooks ** */
hook OnPlayerPassedBanCheck( playerid )
{
	// Pursue a registration check
	mysql_format( dbHandle, szNormalString, sizeof( szNormalString ), "SELECT `NAME` FROM `USERS` WHERE `NAME` = '%e' LIMIT 0,1", ReturnPlayerName( playerid ) );
 	mysql_tquery( dbHandle, szNormalString, "OnPlayerRegisterCheck", "i", playerid );
    return 1;
}

hook OnPlayerDisconnect( playerid, reason )
{
    SavePlayerData( playerid, true );
    return 1;
}

hook OnDialogResponse( playerid, dialogid, response, listitem, inputtext[ ] )
{
    static
        szBigQuery[ 764 ];

    if ( dialogid == DIALOG_LOGIN )
    {
        if ( response )
        {
        	if ( p_PlayerLogged{ playerid } )
        	{
        		AdvancedBan( playerid, "Server", "Exploiting", ReturnPlayerIP( playerid ) );
        		return SendError( playerid, "You are already logged in!" );
        	}

			format( szBigQuery, sizeof( szBigQuery ), "SELECT * FROM `USERS` WHERE `NAME` = '%s' LIMIT 0,1", mysql_escape( ReturnPlayerName( playerid ) ) );
       		mysql_function_query( dbHandle, szBigQuery, true, "OnAttemptPlayerLogin", "ds", playerid, inputtext );
        }
        else return ShowPlayerDialog( playerid, DIALOG_LOGIN_QUIT, DIALOG_STYLE_MSGBOX, "{FFFFFF}Account - Authentication", "{FFFFFF}Are you sure you want to leave the server?", "Yes", "No" );
    }
    else if ( dialogid == DIALOG_LOGIN_QUIT ) {
    	if ( response ) {
    		return Kick( playerid );
    	} else {
	        format( szBigString, sizeof( szBigString ), "{FFFFFF}Welcome, this account ("COL_GREEN"%s"COL_WHITE") is registered.\nPlease enter the password to login.\n\n"COL_GREY"If you are not the owner of this account, leave and rejoin with a different nickname.", ReturnPlayerName( playerid ) );
	        return ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "{FFFFFF}Account - Authentication", szBigString, "Login", "Leave");
    	}
    }
    else if ( dialogid == DIALOG_REGISTER )
    {
        if ( response )
        {
        	if ( p_PlayerLogged{ playerid } )
        		return SendError( playerid, "You are already logged in!" );

            if ( strlen( inputtext ) > 24 || strlen( inputtext ) < 3 )
            {
            	format( szBigQuery, 300, "{FFFFFF}Welcome, this account ("COL_RED"%s"COL_WHITE") is not registered.\nPlease enter your desired password for this account.\n\n"COL_RED"Your password length must vary from 3 to 24 characters.\n\n"COL_GREY"Once you are registered, do not share your password with anyone besides yourself!", ReturnPlayerName( playerid ) );
				ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "{FFFFFF}Account - Register", szBigQuery, "Register", "Leave");
            }
            else
            {
                static
                	szHashed[ 129 ],
                	szSalt[ 25 ],
                	szIP[ 16 ]
                ;

             	randomString( szSalt, 24 );
             	pencrypt( szHashed, sizeof( szHashed ), inputtext, szSalt );
				GetPlayerIp( playerid, szIP, sizeof( szIP ) );

				format( szBigQuery, sizeof( szBigQuery ), "INSERT INTO `USERS` (`NAME`,`PASSWORD`,`SALT`,`IP`,`SCORE`,`CASH`,`ADMINLEVEL`,`BANKMONEY`,`OWNEDHOUSES`,`KILLS`,`DEATHS`,`VIP_PACKAGE`,`OWNEDCARS`,`LASTLOGGED`,`VIP_EXPIRE`,`LAST_SKIN`,`COP_BAN`,`UPTIME`,`ARRESTS`,`FIGHTSTYLE`,`VIPWEP1`,`VIPWEP2`,`VIPWEP3`,`MUTE_TIME`,`WANTEDLVL`,`ROBBERIES`,`PING_IMMUNE`,`FIRES`,`CONTRACTS`,`COP_TUTORIAL`,`JOB`,`LAST_IP`,`ONLINE`) " );
				format( szBigQuery, sizeof( szBigQuery ), "%s VALUES('%s','%s','%s','%s',0,0,0,0,0,1,1,0,0,%d,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,'%s',1)", szBigQuery, mysql_escape( ReturnPlayerName( playerid ) ), szHashed, mysql_escape( szSalt ), mysql_escape( szIP ), g_iTime, mysql_escape( szIP ) );
       			mysql_function_query( dbHandle, szBigQuery, true, "Account_SetAccountID", "d", playerid );

                CallLocalFunction( "OnPlayerRegister", "d", playerid );

				p_JobSet{ playerid } = false;
				//p_CitySet{ playerid } = false;
				p_SpawningCity{ playerid } = CITY_SF;

				p_Uptime[ playerid ] = 0;
				ShowAchievement( playerid, "Registering to SF-CnR!", 1 );
                p_PlayerLogged{ playerid } = true;
                SetPlayerCash( playerid, 0 );
                SetPlayerScore( playerid, 0 );
				p_Kills[ playerid ] = 1;
				p_Deaths[ playerid ] = 1;
				//p_XP[ playerid ] = 0;
				//p_CopTutorial{ playerid } = 0;
				p_OwnedHouses[ playerid ] = 0;
				p_OwnedBusinesses[ playerid ] = 0;
				p_OwnedVehicles[ playerid ] = 0;
				p_Burglaries[ playerid ] = 0;
				ShowPlayerDialog( playerid, DIALOG_ACC_EMAIL, DIALOG_STYLE_INPUT, "{FFFFFF}Account Email", ""COL_WHITE"Would you like to assign an email to your account for security?\n\nWe'll keep you also informed on in-game and community associated events!", "Confirm", "Cancel" );
                SendServerMessage( playerid, "You have "COL_GREEN"successfully{FFFFFF} registered! You have been automatically logged in!" );
            }
        }
        else return ShowPlayerDialog( playerid, DIALOG_REGISTER_QUIT, DIALOG_STYLE_MSGBOX, "{FFFFFF}Account - Authentication", "{FFFFFF}Are you sure you want to leave the server?", "Yes", "No" );
    }
    else if ( dialogid == DIALOG_REGISTER_QUIT ) {
    	if ( response ) {
    		return Kick( playerid );
    	} else {
	        format( szBigString, sizeof( szBigString ), "{FFFFFF}Welcome, this account ("COL_RED"%s"COL_WHITE") is not registered.\nPlease enter your desired password for this account.\n\n"COL_GREY"Once you are registered, do not share your password with anyone besides yourself!", ReturnPlayerName( playerid ) );
	        return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "{FFFFFF}Account - Register", szBigString, "Register", "Leave");
    	}
    }
    return 1;
}

/* ** SQL Threads ** */
thread OnPlayerRegisterCheck( playerid )
{
	if ( GetPVarInt( playerid, "banned_connection" ) == 1 ) return 1; // Stop anything from happening.

	new
	    rows, fields
	;
    cache_get_data( rows, fields );
	if ( rows )
    {
        format( szBigString, sizeof( szBigString ), "{FFFFFF}Welcome, this account ("COL_GREEN"%s"COL_WHITE") is registered.\nPlease enter the password to login.\n\n"COL_GREY"If you are not the owner of this account, leave and rejoin with a different nickname.", ReturnPlayerName( playerid ) );
        ShowPlayerDialog( playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "{FFFFFF}Account - Authentication", szBigString, "Login", "Leave" );
    }
    else
    {
		mysql_format( dbHandle, szNormalString, sizeof( szNormalString ), "SELECT `IP` FROM `USERS` WHERE `IP` = '%e' LIMIT 5", ReturnPlayerIP( playerid ) );
 		mysql_tquery( dbHandle, szNormalString, "OnPlayerDuplicateAccountCheck", "i", playerid );
    }
	return 1;
}

thread OnPlayerDuplicateAccountCheck( playerid )
{
	new
		rows, fields;

	cache_get_data( rows, fields );

	if ( rows > 10 )
	{
		SendError( playerid, "Sorry, this IP has more than 10 users registered to it which is the maximum limit of users per IP." );
		KickPlayerTimed( playerid );
	}
	else
	{
        format( szBigString, sizeof( szBigString ), "{FFFFFF}Welcome, this account ("COL_RED"%s"COL_WHITE") is not registered.\nPlease enter your desired password for this account.\n\n"COL_GREY"Once you are registered, do not share your password with anyone besides yourself!", ReturnPlayerName( playerid ) );
        ShowPlayerDialog( playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "{FFFFFF}Account - Register", szBigString, "Register", "Leave" );
	}
	return 1;
}

thread OnAttemptPlayerLogin( playerid, password[ ] )
{
	new
	    rows, fields
	;
    cache_get_data( rows, fields );

    if ( rows )
    {
    	new
    		szHashed[ 129 ],
    		szPassword[ 129 ],
    		szSalt[ 25 ],
    		bool: isSalted = false
    	;

		cache_get_field_content( 0,  "SALT", szSalt );
		cache_get_field_content( 0,  "PASSWORD", szPassword );

		if ( !strcmp( szSalt, "NULL", false ) ) // User doesn't have a salt
		{
			WP_Hash( szHashed, sizeof( szHashed ), password );
			isSalted = false;
		}
		else
		{
			pencrypt( szHashed, sizeof( szHashed ), password, szSalt );
			isSalted = true;
		}

		if ( ! strcmp( szHashed, szPassword, false ) )
    	{
    		if ( !isSalted ) // Converting from insecure to secure
    		{
             	randomString( szSalt, 24 );
             	pencrypt( szHashed, sizeof( szHashed ), password, szSalt );

    			format( szBigString, sizeof( szBigString ), "UPDATE USERS SET `PASSWORD`='%s', `SALT`='%s' WHERE `NAME`='%s'", szHashed, mysql_escape( szSalt ), ReturnPlayerName( playerid ) );
    			mysql_single_query( szBigString );
    		}

    		p_AccountID[ playerid ] = cache_get_field_content_int( 0, "ID", dbHandle );

			new iScore 		= cache_get_field_content_int( 0, "SCORE", dbHandle );
			new iCash 		= cache_get_field_content_int( 0, "CASH", dbHandle );
			new iFightStyle = cache_get_field_content_int( 0, "FIGHTSTYLE", dbHandle );
			new iWanted 	= cache_get_field_content_int( 0, "WANTEDLVL", dbHandle );

			SetPlayerCash			( playerid, iCash );
			SetPlayerScore			( playerid, iScore );
			SetPlayerFightingStyle	( playerid, iFightStyle );

			if ( iWanted ) {
				SetPlayerWantedLevel( playerid, iWanted );
				SendClientMessageFormatted( playerid, -1, ""COL_GOLD"[RESUME]{FFFFFF} Your wanted level has been set to %d as you are resuming your life.", GetPlayerWantedLevel( playerid ) );
			}

			p_AdminLevel[ playerid ] 		= cache_get_field_content_int( 0, "ADMINLEVEL", dbHandle );
			SetPlayerBankMoney( playerid, cache_get_field_content_int( 0, "BANKMONEY", dbHandle ) );
			p_Kills[ playerid ] 			= cache_get_field_content_int( 0, "KILLS", dbHandle );
			p_Deaths[ playerid ] 			= cache_get_field_content_int( 0, "DEATHS", dbHandle );
			p_VIPLevel[ playerid ] 			= cache_get_field_content_int( 0, "VIP_PACKAGE", dbHandle );
			//p_XP[ playerid ] 				= cache_get_field_content_int( 0, "XP", dbHandle );
			p_VIPExpiretime[ playerid ] 	= cache_get_field_content_int( 0, "VIP_EXPIRE", dbHandle );
			p_LastSkin[ playerid ] 			= cache_get_field_content_int( 0, "LAST_SKIN", dbHandle );
			p_Burglaries[ playerid ] 		= cache_get_field_content_int( 0, "BURGLARIES", dbHandle );
			p_CopBanned{ playerid } 		= cache_get_field_content_int( 0, "COP_BAN", dbHandle );
			p_ArmyBanned{ playerid } 		= cache_get_field_content_int( 0, "ARMY_BAN", dbHandle );
			p_Uptime[ playerid ] 			= cache_get_field_content_int( 0, "UPTIME", dbHandle );
			p_Arrests[ playerid ] 			= cache_get_field_content_int( 0, "ARRESTS", dbHandle );
			p_VIPWep1{ playerid } 			= cache_get_field_content_int( 0, "VIPWEP1", dbHandle );
			p_VIPWep2{ playerid } 			= cache_get_field_content_int( 0, "VIPWEP2", dbHandle );
			p_VIPWep3{ playerid } 			= cache_get_field_content_int( 0, "VIPWEP3", dbHandle );
			p_MutedTime[ playerid ] 		= cache_get_field_content_int( 0, "MUTE_TIME", dbHandle );
			p_Robberies[ playerid ] 		= cache_get_field_content_int( 0, "ROBBERIES", dbHandle );
			p_Fires[ playerid ] 			= cache_get_field_content_int( 0, "FIRES", dbHandle );
			p_PingImmunity{ playerid } 		= cache_get_field_content_int( 0, "PING_IMMUNE", dbHandle );
			p_HitsComplete[ playerid ] 		= cache_get_field_content_int( 0, "CONTRACTS", dbHandle );
			p_TruckedCargo[ playerid ] 		= cache_get_field_content_int( 0, "TRUCKED", dbHandle );
			p_PilotMissions[ playerid ] 	= cache_get_field_content_int( 0, "PILOT", dbHandle );
			//p_TrainMissions[ playerid ] 	= cache_get_field_content_int( 0, "TRAIN", dbHandle );
			//p_CopTutorial{ playerid } 		= cache_get_field_content_int( 0, "COP_TUTORIAL", dbHandle );
			p_Job{ playerid } 				= cache_get_field_content_int( 0, "JOB", dbHandle );
			p_VIPJob{ playerid } 			= cache_get_field_content_int( 0, "VIP_JOB", dbHandle );
			p_AdminJailed{ playerid } 		= cache_get_field_content_int( 0, "JAIL_ADMIN", dbHandle );
			p_JailTime[ playerid ] 			= cache_get_field_content_int( 0, "JAIL_TIME", dbHandle );
			p_Ropes[ playerid ] 			= cache_get_field_content_int( 0, "ROPES", dbHandle );
			p_MetalMelter[ playerid ] 		= cache_get_field_content_int( 0, "MELTERS", dbHandle );
			p_Scissors[ playerid ] 			= cache_get_field_content_int( 0, "SCISSORS", dbHandle );
			p_AntiEMP[ playerid ] 			= cache_get_field_content_int( 0, "FOILS", dbHandle );
			p_BobbyPins[ playerid ] 		= cache_get_field_content_int( 0, "PINS", dbHandle );
			p_ContractedAmount[ playerid ] 	= cache_get_field_content_int( 0, "BOUNTY", dbHandle );
			p_WeedGrams[ playerid ] 		= cache_get_field_content_int( 0, "WEED", dbHandle );
			p_SpawningCity{ playerid } 		= cache_get_field_content_int( 0, "CITY", dbHandle );
			SetPlayerMeth( playerid, cache_get_field_content_int( 0, "METH", dbHandle ) );
			SetPlayerCausticSoda( playerid, cache_get_field_content_int( 0, "SODA", dbHandle ) );
			SetPlayerMuriaticAcid( playerid, cache_get_field_content_int( 0, "ACID", dbHandle ) );
			SetPlayerHydrogenChloride( playerid, cache_get_field_content_int( 0, "GAS", dbHandle ) );
			p_LeftCuffed{ playerid } 		= !!cache_get_field_content_int( 0, "IS_CUFFED", dbHandle );
			p_JailsBlown[ playerid ] 		= cache_get_field_content_int( 0, "BLEW_JAILS", dbHandle );
			p_BankBlown[ playerid ] 		= cache_get_field_content_int( 0, "BLEW_VAULT", dbHandle );
			p_CarsJacked[ playerid ] 		= cache_get_field_content_int( 0, "VEHICLES_JACKED", dbHandle );
			p_MethYielded[ playerid ] 		= cache_get_field_content_int( 0, "METH_YIELDED", dbHandle );
			SetPlayerDrillStrength( playerid, cache_get_field_content_int( 0, "DRILL", dbHandle ) );
			SetPlayerIrresistibleCoins( playerid, cache_get_field_content_float( 0, "COINS", dbHandle ) );
			SetPlayerExtraSlots( playerid, cache_get_field_content_int( 0, "EXTRA_SLOTS", dbHandle ) );
			p_forcedAnticheat[ playerid ] 	= cache_get_field_content_int( 0, "FORCE_AC", dbHandle );
			SetPlayerCasinoRewardsPoints( playerid, cache_get_field_content_float( 0, "CASINO_REWARDS", dbHandle ) );
			SetPlayerCasinoHighroller( playerid, !!cache_get_field_content_int( 0, "VISAGE_HIGHROLLER", dbHandle ) );
			p_Fireworks[ playerid ] = cache_get_field_content_int( 0, "FIREWORKS", dbHandle );
			p_ExplosiveBullets[ playerid ] = cache_get_field_content_int( 0, "EXPLOSIVE_BULLETS", dbHandle );
			p_AddedEmail{ playerid } = !!cache_get_field_content_int( 0, "USED_EMAIL", dbHandle );
			// p_TaxTime[ playerid ] = cache_get_field_content_int( 0, "TAX_TIME", dbHandle );

			SetPlayerC4Amount( playerid, cache_get_field_content_int( 0, "C4", dbHandle ) );
			SetPlayerSeasonalXP( playerid, cache_get_field_content_float( 0, "RANK", dbHandle ) );
            SetPlayerFindOrCreateGang( playerid, cache_get_field_content_int( 0, "GANG_ID", dbHandle ) );

			// spawn location
			new
				spawn_location[ 10 ];

			cache_get_field_content( 0, "SPAWN", spawn_location, dbHandle, sizeof( spawn_location ) );

			if ( ismysqlnull( spawn_location ) || sscanf( spawn_location, "s[4]d", p_SpawningKey[ playerid ], p_SpawningIndex[ playerid ] ) ) {
				p_SpawningKey[ playerid ] [ 0 ] = '\0', p_SpawningIndex[ playerid ] = 0;
			}

			// anti-cheat
			if ( p_forcedAnticheat[ playerid ] > 0 && ! IsPlayerUsingSampAC( playerid ) ) {
				SendError( playerid, "You must install an anticheat to play the server. Visit "COL_GREY""AC_WEBSITE""COL_WHITE" to install the anticheat." );
				KickPlayerTimed( playerid );
				return 1;
			}

			// Load some other variables too
		   	p_OwnedHouses 		[ playerid ] = GetPlayerOwnedHouses( playerid );
		   	p_OwnedBusinesses 	[ playerid ] = GetPlayerOwnedBusinesses( playerid );

		    p_PlayerLogged	{ playerid } = true;
			p_JobSet 		{ playerid } = true;
			// p_CitySet 	{ playerid } = true;
			p_Muted 		{ playerid } = p_MutedTime[ playerid ] > 0 ? true : false; // Save muting :X

			// Load other player related variables
			CallLocalFunction( "OnPlayerLogin", "d", playerid );

			// Player is online
			mysql_single_query( sprintf( "UPDATE `USERS` SET `ONLINE`=1 WHERE `ID`=%d", p_AccountID[ playerid ] ) );

			// Log in player
		  	SendServerMessage( playerid, "You have " COL_GREEN "successfully" COL_WHITE " logged in!" );

			// Chat Ban Player
			format( szBigString, sizeof( szBigString ), "SELECT * FROM `CHAT_BANS` WHERE `ID` = '%d' LIMIT 0,1", p_AccountID[ playerid ] );
			mysql_function_query( dbHandle, szBigString, true, "ChatBanUponLogin", "d", playerid );
		}
	    else
	    {
	        p_IncorrectLogins{ playerid } ++;
	        format( szBigString, sizeof( szBigString ), "{FFFFFF}Welcome, this account ("COL_GREEN"%s"COL_WHITE") is registered.\nPlease enter the password to login.\n\n"COL_RED"Wrong password! Try again! [%d/3]\n\n"COL_GREY"If you are not the owner of this account, leave and rejoin with a different nickname.", ReturnPlayerName( playerid ), p_IncorrectLogins{ playerid } );
			ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "{FFFFFF}Account - Login", szBigString, "Login", "Leave");
			if ( p_IncorrectLogins{ playerid } >= 3 ) {
			    p_IncorrectLogins{ playerid } = 0;
				SendServerMessage( playerid, "You have been kicked for too many incorrect login attempts." );
				KickPlayerTimed( playerid );
			}
	    }
    }
    else
    {
    	Kick( playerid );
    	printf( "User::Error - User Not Created Attempting Login" );
    }
	return 1;
}

thread Account_SetAccountID( playerid )
{
	p_AccountID[ playerid ]	= cache_insert_id( );
	return 1;
}

/* ** Functions ** */
stock pencrypt( szLeFinale[ ], iSize = sizeof( szLeFinale ), szPassword[ ], szSalt[ 25 ], iPepper = 24713018, szCost[ 3 ] = "2y" ) // lorenc's hashing algorithm
{
	static
    	szHash[ 256 ];

    WP_Hash( szHash, sizeof( szHash ), szPassword );

    format( szHash, sizeof( szHash ), "%s%d%s$%s$", szSalt, iPepper, szHash, szCost );

    WP_Hash( szLeFinale, iSize, szHash );
}

stock SavePlayerData( playerid, bool: logout = false )
{
    static
		Query[ 950 ];

	if ( IsPlayerNPC( playerid ) )
		return 0;

    if ( p_PlayerLogged{ playerid } )
    {
    	new
    		bool: bQuitToAvoid = false;

		if ( IsPlayerCuffed( playerid ) || IsPlayerTazed( playerid ) || IsPlayerTied( playerid ) || p_LeftCuffed{ playerid } || p_QuitToAvoidTimestamp[ playerid ] > g_iTime )
			bQuitToAvoid = true;

        format( Query, sizeof( Query ), "UPDATE `USERS` SET `SCORE`=%d,`ADMINLEVEL`=%d,`OWNEDHOUSES`=%d,`KILLS`=%d,`DEATHS`=%d,`VIP_PACKAGE`=%d,`OWNEDCARS`=%d,`LASTLOGGED`=%d,`VIP_EXPIRE`=%d,`LAST_SKIN`=%d,`BURGLARIES`=%d,`UPTIME`=%d,`ARRESTS`=%d,`CITY`=%d,`METH`=%d,`SODA`=%d,`ACID`=%d,`GAS`=%d,",
                                       	GetPlayerScore( playerid ), 	p_AdminLevel[ playerid ],
                                    	p_OwnedHouses[ playerid ], 		p_Kills[ playerid ],
										p_Deaths[ playerid ], 			p_VIPLevel[ playerid ],
										p_OwnedVehicles[ playerid ], 	g_iTime, 						p_VIPExpiretime[ playerid ],
										p_LastSkin[ playerid ], 		p_Burglaries[ playerid ], 		p_Uptime[ playerid ],
									 	p_Arrests[ playerid ],			p_SpawningCity{ playerid },		GetPlayerMeth( playerid ),
										GetPlayerCausticSoda( playerid ), GetPlayerMuriaticAcid( playerid ), GetPlayerHydrogenChloride( playerid ) );

		format( Query, sizeof( Query ), "%s`VIPWEP1`=%d,`VIPWEP2`=%d,`VIPWEP3`=%d,`MUTE_TIME`=%d,`WANTEDLVL`=%d,`ROBBERIES`=%d,`PING_IMMUNE`=%d,`FIRES`=%d,`CONTRACTS`=%d,`JOB`=%d,`JAIL_TIME`=%d,`ROPES`=%d,`MELTERS`=%d,`SCISSORS`=%d,`FOILS`=%d,`PINS`=%d,`BOUNTY`=%d,`WEED`=%d,`IS_CUFFED`=%d,`DRILL`=%d,",
										Query,                          p_VIPWep1{ playerid },          p_VIPWep2{ playerid },
										p_VIPWep3{ playerid },          p_MutedTime[ playerid ],        p_WantedLevel[ playerid ],
										p_Robberies[ playerid ],        p_PingImmunity{ playerid },     p_Fires[ playerid ],
										p_HitsComplete[ playerid ],     p_Job{ playerid },              p_JailTime[ playerid ],
										p_Ropes[ playerid ],			p_MetalMelter[ playerid ],
										p_Scissors[ playerid ], 		p_AntiEMP[ playerid ], 			p_BobbyPins[ playerid ],
										p_ContractedAmount[ playerid ],	p_WeedGrams[ playerid ],		logout ? ( bQuitToAvoid ? 1 : 0 ) : 0,
										GetPlayerDrillStrength( playerid ) );

		format( Query, sizeof( Query ), "%s`BLEW_JAILS`=%d,`BLEW_VAULT`=%d,`VEHICLES_JACKED`=%d,`METH_YIELDED`=%d,`LAST_IP`='%s',`VIP_JOB`=%d,`TRUCKED`=%d,`EXPLOSIVE_BULLETS`=%d,`ONLINE`=%d,`PILOT`=%d WHERE `ID`=%d",
										Query,
										p_JailsBlown[ playerid ], 		p_BankBlown[ playerid ], 			p_CarsJacked[ playerid ],
										p_MethYielded[ playerid ],		mysql_escape( ReturnPlayerIP( playerid ) ),
										p_VIPJob{ playerid },			p_TruckedCargo[ playerid ],
										p_ExplosiveBullets[ playerid ],
										!logout,
										p_PilotMissions[ playerid ],
										p_AccountID[ playerid ] );

		mysql_single_query( Query );

        if ( logout )
		    p_PlayerLogged{ playerid } = false;
    }
    return 1;
}

stock GetPlayerAccountID( playerid ) return p_AccountID[ playerid ];

stock IsPlayerLoggedIn( playerid ) return p_PlayerLogged{ playerid };