SA-MP Forums Archive
Player positions not saved properly - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+--- Thread: Player positions not saved properly (/showthread.php?tid=656850)



Player positions not saved properly - OMonger - 25.07.2018

Hi.

I've ran into a problem where my player position script only saves 4 numbers and no decimal points. I'm using mysql here is my script for saving positions:

PHP код:
stock SavePlayerPos(playerid)
{
    new 
query[500], Float:posXFloat:posYFloat:posZ;
    
GetPlayerPos(playeridposXposYposZ);
    
format(querysizeof(query), "UPDATE `accounts` SET `playerX` = '%f', `playerY` = '%f', `playerZ` = '%f' WHERE `playerName` = '%s'"posXposYposZplayerInfo[playerid][playerName]);
    
mysql_tquery(Databasequery);

Please help


Re: Player positions not saved properly - RedRex - 25.07.2018

What is the errors?


Re: Player positions not saved properly - SyS - 25.07.2018

Check your field' data type


Re: Player positions not saved properly - OMonger - 25.07.2018

The error is that it isn't saving the players positions completely. For example, the players (and y and z) are all saved as a whole number rather than the full number of: "1911" instead of the actual position of: "1911.1234".

@SyS, how do I check this?


Re: Player positions not saved properly - SyS - 25.07.2018

Quote:
Originally Posted by OMonger
Посмотреть сообщение
@SyS, how do I check this?
Check for the data type of field (playerX,playerY,playerZ) in your CREATE TABLE query or you can check the same from phpmyadmin


Re: Player positions not saved properly - OMonger - 25.07.2018

Thanks Sys! Problem was it wasn't set to a float. Working now


Re: Player positions not saved properly - OMonger - 25.07.2018

I've got another problem. Basically on my load player, it doesn't load the players position properly. It always spawns them at the blueberry farm instead of their most recent position before leaving. Here are the codes that could be affecting this:
PHP код:
Of course on the dialog login it allows them to access the request class, and with or without the logged in statement on requestclass does not affect results
 
public OnPlayerRequestClass(playeridclassid)
{
    if(
playerInfo[playerid][LoggedIn] == true)
    {
        new 
Float:posXFloat:posYFloat:posZ;
        
cache_get_value_name_float(0"playerX"posX);
        
cache_get_value_name_float(0"playerY"posY);
        
cache_get_value_name_float(0"playerZ",posZ);
        
SetSpawnInfoplayerid00posXposYposZ000000);
        
SpawnPlayer(playerid);
    }
    return 
1;
}
 
stock LoadPlayerStats(playerid)
{
    if(
playerInfo[playerid][LoggedIn] ==  true)
    {
        new 
query[200], name[24];
        
GetPlayerName(playeridname24);
        
format(querysizeof(query), "SELECT * FROM `accounts` WHERE `playerName` = '%s'"name);
        
mysql_tquery(Databasequery);
        
playerInfo[playerid][playerAdmin] = cache_get_value_int(0"playerAdmin"playerInfo[playerid][playerAdmin]);
        
playerInfo[playerid][playerMod] = cache_get_value_int(0"playerMod"playerInfo[playerid][playerMod]);
        
playerInfo[playerid][playerHelper] = cache_get_value_int(0"playerHelper"playerInfo[playerid][playerHelper]);
        
playerInfo[playerid][playerLevel] = cache_get_value_int(0"playerLevel"playerInfo[playerid][playerLevel]);
        
playerInfo[playerid][playerCash] = cache_get_value_int(0"playerCash"playerInfo[playerid][playerCash]);
        
SetPlayerScore(playeridplayerInfo[playerid][playerLevel]);
        
GivePlayerMoney(playeridplayerInfo[playerid][playerCash]);
        
printf("player loaded.");
    }




Re: Player positions not saved properly - AmigaBlizzard - 25.07.2018

When working with tqueries, you need to load your data using callback functions.
You can't read the data right after sending the query because there is no result yet.
PHP код:
stock LoadPlayerStats(playerid)
{
    if(
playerInfo[playerid][LoggedIn] ==  true)
    {
        new 
query[200], name[24];
        
GetPlayerName(playeridname24);
    
mysql_format(SQL_dbquerysizeof(query), "SELECT * FROM `accounts` WHERE `playerName` = '%e'"name);
    
mysql_tquery(SQL_dbquery"Player_OnDataLoad""i"playerid);
    }
}
forward Player_OnDataLoad(playerid);
public 
Player_OnDataLoad(playerid)
{
playerInfo[playerid][playerAdmin] = cache_get_value_int(0"playerAdmin"playerInfo[playerid][playerAdmin]);
        
playerInfo[playerid][playerMod] = cache_get_value_int(0"playerMod"playerInfo[playerid][playerMod]);
        
playerInfo[playerid][playerHelper] = cache_get_value_int(0"playerHelper"playerInfo[playerid][playerHelper]);
        
playerInfo[playerid][playerLevel] = cache_get_value_int(0"playerLevel"playerInfo[playerid][playerLevel]);
        
playerInfo[playerid][playerCash] = cache_get_value_int(0"playerCash"playerInfo[playerid][playerCash]);
        
SetPlayerScore(playeridplayerInfo[playerid][playerLevel]);
        
GivePlayerMoney(playeridplayerInfo[playerid][playerCash]); 
        
cache_get_value_name_float(0"playerX"playerInfo[playerid][spawnX]);
        
cache_get_value_name_float(0"playerY"playerInfo[playerid][spawnY]);
        
cache_get_value_name_float(0"playerZ",playerInfo[playerid][spawnZ]);
    return 
1;
}
public 
OnPlayerRequestClass(playeridclassid)
{
    if(
playerInfo[playerid][LoggedIn] == true)
    {
        
SetSpawnInfoplayerid00playerInfo[playerid][spawnX], playerInfo[playerid][spawnY], playerInfo[playerid][spawnZ], 000000);
        
SpawnPlayer(playerid);
    }
    return 
1;

Also load the position of the player in this callback and store it in your playerinfo array as well.
Then you can use it directly in your OnPlayerRequestClass callback.

You were trying to read data from a non-existing cache, directly into the OnPlayerRequestClass callback, which didn't receive a cache object.
Didn't you get errors in your mysql-log about this?

Another piece of advice: when using mysql with strings like a player's name, always escape the string to prevent mysql injection.
Instead of using format, use mysql_format like in my code and don't use %s but use %e.
This automatically escapes strings.
If you don't, someday your database may be wiped clean.

PHP код:
SELECT FROM `accountsWHERE `playerName` = '%s' 
Consider this query.
Now if someone would login with his name set to:
PHP код:
'; DROP TABLE 'accounts';' 
A little weird, but it happens.
Your query would end up like this:
PHP код:
SELECT FROM `accountsWHERE `playerName` = ''DROP TABLE 'accounts';'' 
This would firstly load no accounts from your database since the data-part is empty, probably confusing your loading function.
But the worst of all, the DROP TABLE command which follows, will simply delete your accounts table without even asking if it's convenient.

Using mysql_format with %e for strings prevents this.