Veteran Member
Join Date: Nov 2007
Location: Fishdot Nation
|
07-17-2010
, 18:43
[Tut] MySql - Save/Load/Usefull Things (Xp Mod)
|
#1
|
Hello there,
Ive decided to write this down as an addition to the other tutorial here :
http://forums.alliedmods.net/showthread.php?t=66497
But then I would be using MySql. I will try to keep it simple and focus more on the mysql part then on the xp mod itself.
Be aware, when reading this you should have basic knowledge about pawn coding, I will try to learn you something about mysql coding on this tutorial.
We will start with a main plugin :
PHP Code:
#include <amxmodx>
#define PLUGIN "Tutorial" #define VERSION "1.0" #define AUTHOR "Grim"
new iExp[33]
// Pcvar's new cKill new cHeadshot new cDeath
public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) register_event("DeathMsg", "Event_DeathMsg", "a") // Register death event // register the Pcvar's cKill = register_cvar("exp_kill", "2") cHeadshot = register_cvar("exp_headshot", "4") cDeath = register_cvar("exp_death", "1") }
public Event_DeathMsg() { new iKiller = read_data(1) // read the data to get the killer and victim new iVictim = read_data(2) if(is_user_alive(iKiller)) // Check if the killer is alive in case he killed himself { if(read_data(3)) // Check if it was a headshot { iExp[iKiller] += get_pcvar_num(cHeadshot) // Add the amount of the Pcvar to iExp } else { iExp[iKiller] += get_pcvar_num(cKill) } } iExp[iVictim] -= get_pcvar_num(cDeath) // Decrease the amount of the Pcvar from iExp }
Then we start adding mysql to it.
First include sqlx
PHP Code:
#include <sqlx>
Then we start to create a mysql init
PHP Code:
// Credits to hawk552 from hes old tutorial
public MySql_Init() { // we tell the API that this is the information we want to connect to, // just not yet. basically it's like storing it in global variables g_SqlTuple = SQL_MakeDbTuple(Host,User,Pass,Db) // ok, we're ready to connect new ErrorCode,Handle:SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,g_Error,charsmax(g_Error)) if(SqlConnection == Empty_Handle) // stop the plugin with an error message set_fail_state(g_Error) new Handle:Queries // we must now prepare some random queries Queries = SQL_PrepareQuery(SqlConnection,"CREATE TABLE IF NOT EXISTS tutorial (steamid varchar(32),exp INT(11))")
if(!SQL_Execute(Queries)) { // if there were any problems the plugin will set itself to bad load. SQL_QueryError(Queries,g_Error,charsmax(g_Error)) set_fail_state(g_Error) } // Free the querie SQL_FreeHandle(Queries) // you free everything with SQL_FreeHandle SQL_FreeHandle(SqlConnection) }
To prevent errors we free the handle at a mapend
PHP Code:
public plugin_end() { // free the tuple - note that this does not close the connection, // since it wasn't connected in the first place SQL_FreeHandle(g_SqlTuple) }
Now we need to load and save the player hes stats
PHP Code:
public Load_MySql(id) { new szSteamId[32], szTemp[512] get_user_authid(id, szSteamId, charsmax(szSteamId)) new Data[1] Data[0] = id //we will now select from the table `tutorial` where the steamid match format(szTemp,charsmax(szTemp),"SELECT * FROM `tutorial` WHERE (`tutorial`.`steamid` = '%s')", szSteamId) SQL_ThreadQuery(g_SqlTuple,"register_client",szTemp,Data,1) }
public register_client(FailState,Handle:Query,Error[],Errcode,Data[],DataSize) { if(FailState == TQUERY_CONNECT_FAILED) { log_amx("Load - Could not connect to SQL database. [%d] %s", Errcode, Error) } else if(FailState == TQUERY_QUERY_FAILED) { log_amx("Load Query failed. [%d] %s", Errcode, Error) }
new id id = Data[0] if(SQL_NumResults(Query) < 1) { //.if there are no results found new szSteamId[32] get_user_authid(id, szSteamId, charsmax(szSteamId)) // get user's steamid // if its still pending we can't do anything with it if (equal(szSteamId,"ID_PENDING")) return PLUGIN_HANDLED new szTemp[512] // now we will insturt the values into our table. format(szTemp,charsmax(szTemp),"INSERT INTO `tutorial` ( `steamid` , `exp`)VALUES ('%s','0');",szSteamId) SQL_ThreadQuery(g_SqlTuple,"IgnoreHandle",szTemp) } else { // if there are results found iExp[id] = SQL_ReadResult(Query, 1) } return PLUGIN_HANDLED }
PHP Code:
public Save_MySql(id) { new szSteamId[32], szTemp[512] get_user_authid(id, szSteamId, charsmax(szSteamId)) // Here we will update the user hes information in the database where the steamid matches. format(szTemp,charsmax(szTemp),"UPDATE `tutorial` SET `exp` = '%i' WHERE `tutorial`.`steamid` = '%s';",iExp[id], szSteamId) SQL_ThreadQuery(g_SqlTuple,"IgnoreHandle",szTemp) }
Now our final code will look like this :
PHP Code:
#include <amxmodx> #include <sqlx>
#define PLUGIN "Tutorial" #define VERSION "1.0" #define AUTHOR "Grim"
// Ur Mysql Information new Host[] = "hostname" new User[] = "username" new Pass[] = "password" new Db[] = "database"
new Handle:g_SqlTuple new g_Error[512]
new iExp[33]
// Pcvar's new cKill new cHeadshot new cDeath
public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) register_event("DeathMsg", "Event_DeathMsg", "a") // Register death event // register the Pcvar's cKill = register_cvar("exp_kill", "2") cHeadshot = register_cvar("exp_headshot", "4") cDeath = register_cvar("exp_death", "1") set_task(1.0, "MySql_Init") // set a task to activate the mysql_init }
public MySql_Init() { // we tell the API that this is the information we want to connect to, // just not yet. basically it's like storing it in global variables g_SqlTuple = SQL_MakeDbTuple(Host,User,Pass,Db) // ok, we're ready to connect new ErrorCode,Handle:SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,g_Error,charsmax(g_Error)) if(SqlConnection == Empty_Handle) // stop the plugin with an error message set_fail_state(g_Error) new Handle:Queries // we must now prepare some random queries Queries = SQL_PrepareQuery(SqlConnection,"CREATE TABLE IF NOT EXISTS tutorial (steamid varchar(32),exp INT(11))")
if(!SQL_Execute(Queries)) { // if there were any problems SQL_QueryError(Queries,g_Error,charsmax(g_Error)) set_fail_state(g_Error) } // close the handle SQL_FreeHandle(Queries) // you free everything with SQL_FreeHandle SQL_FreeHandle(SqlConnection) }
public plugin_end() { // free the tuple - note that this does not close the connection, // since it wasn't connected in the first place SQL_FreeHandle(g_SqlTuple) }
public Load_MySql(id) { new szSteamId[32], szTemp[512] get_user_authid(id, szSteamId, charsmax(szSteamId)) new Data[1] Data[0] = id //we will now select from the table `tutorial` where the steamid match format(szTemp,charsmax(szTemp),"SELECT * FROM `tutorial` WHERE (`tutorial`.`steamid` = '%s')", szSteamId) SQL_ThreadQuery(g_SqlTuple,"register_client",szTemp,Data,1) }
public register_client(FailState,Handle:Query,Error[],Errcode,Data[],DataSize) { if(FailState == TQUERY_CONNECT_FAILED) { log_amx("Load - Could not connect to SQL database. [%d] %s", Errcode, Error) } else if(FailState == TQUERY_QUERY_FAILED) { log_amx("Load Query failed. [%d] %s", Errcode, Error) }
new id id = Data[0] if(SQL_NumResults(Query) < 1) { //.if there are no results found new szSteamId[32] get_user_authid(id, szSteamId, charsmax(szSteamId)) // get user's steamid // if its still pending we can't do anything with it if (equal(szSteamId,"ID_PENDING")) return PLUGIN_HANDLED new szTemp[512] // now we will insturt the values into our table. format(szTemp,charsmax(szTemp),"INSERT INTO `tutorial` ( `steamid` , `exp`)VALUES ('%s','0');",szSteamId) SQL_ThreadQuery(g_SqlTuple,"IgnoreHandle",szTemp) } else { // if there are results found iExp[id] = SQL_ReadResult(Query, 1) } return PLUGIN_HANDLED }
public Save_MySql(id) { new szSteamId[32], szName[32], szTemp[512] get_user_authid(id, szSteamId, charsmax(szSteamId)) // Here we will update the user hes information in the database where the steamid matches. format(szTemp,charsmax(szTemp),"UPDATE `tutorial` SET `exp` = '%i' WHERE `tutorial`.`steamid` = '%s';",iExp[id], szSteamId) SQL_ThreadQuery(g_SqlTuple,"IgnoreHandle",szTemp) }
public IgnoreHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize) { SQL_FreeHandle(Query) return PLUGIN_HANDLED }
public client_putinserver(id) { Load_MySql(id) }
public client_disconnect(id) { Save_MySql(id) }
public Event_DeathMsg() { new iKiller = read_data(1) // read the data to get the killer and victim new iVictim = read_data(2) if(is_user_alive(iKiller)) // Check if the killer is alive in case he killed himself { if(read_data(3)) { iExp[iKiller] += get_pcvar_num(cHeadshot) // Add the amount of the Pcvar to iExp } else { iExp[iKiller] += get_pcvar_num(cKill) } } iExp[iVictim] -= get_pcvar_num(cDeath) // Decrease the amount of the Pcvar from iExp }
Credits to hawk552 from hes old tutorial -
http://forums.alliedmods.net/showthr...ighlight=mysql
Good to know
Get a ranking :
PHP Code:
public Show_Rank(id) // register cmd to this function { for(new i; i < MaxPlayers; i++) { if(is_user_connected(i)) Save_MySql(i) // Save all stats to get the correct rank } new Data[1] Data[0] = id new szTemp[512] format(szTemp,charsmax(szTemp),"SELECT COUNT(*) FROM `tutorial` WHERE `exp` >= %d", Exp[id]) // Select the count where the exp is matching or higher (Incase of equal exp) SQL_ThreadQuery(g_SqlTuple,"Sql_Rank",szTemp,Data,1) return PLUGIN_CONTINUE }
public Sql_Rank(FailState,Handle:Query,Error[],Errcode,Data[],DataSize) { if(FailState == TQUERY_CONNECT_FAILED) log_amx("Load - Could not connect to SQL database. [%d] %s", Errcode, Error) else if(FailState == TQUERY_QUERY_FAILED) log_amx("Load Query failed. [%d] %s", Errcode, Error) new count = 0 count = SQL_ReadResult(Query,0) if(count == 0) count = 1 new id id = Data[0]
client_print(id, print_chat, "You're rank is %i with %i exp", count, Exp[id]); return PLUGIN_HANDLED }
How to store floats:
PHP Code:
//example Queries[0] = SQL_PrepareQuery(SqlConnection, "CREATE TABLE IF NOT EXISTS %s (steamid varchar(32), yourfloat FLOAT(11,3))", szTableName);
// FLOAT(11,3) // 11 = maximum number of digits // 3 = maximum number of digits behind the decimal point
// Load data
new Float:yourfloat SQL_ReadResult( Query, Column, yourfloat );
How to delete rows:
PHP Code:
new szTemp[256], Data[1];
Data[0] = id
format(szTemp,charsmax(szTemp),"DELETE FROM `%s` WHERE `steamid` = '%s'", szMainTable, szSteamid); SQL_ThreadQuery(SqlTuple,"IgnoreHandle",szTemp,Data,1);
ToDo List
- Adding more examples.
Common mistakes
- Ur mysql database does not support external connections.
- 1 of the 4 informations you fill in is not correct. (username, password, hostname, databasename)
- Ur created table differences from the updating you are doing the a record (look @ https://forums.alliedmods.net/showthread.php?t=133063 )
Any suggestions to add? Have u seen mistakes?
Please report them.
Greetings Grim
__________________
Last edited by grimvh2; 04-20-2011 at 19:01.
|
|