Bueno, como eh visto muchos sistemas de guardado en sqlite/MySql pero ningún tutorial sobre cómo funciona o como se hace, me tomare el tiempo de hacer un tutorial sobre el tema de guardar datos en sqlite
Para poder entender cómo funciona se necesitan conocimientos previos sobre pawn (nivel medio) y conocimientos sobre SQL (igual explicaré en este post) bueno empecemos
Primero explicaré cómo funciona el lenguaje SQL, no hay mucho que decir ya que es un lenguaje muy pero muy simple, es inglés básico, simplemente hay que saber cómo realizar una consulta (query) adecuadamente para poderla llevar a cabo, veamos algunos ejemplos
Primero que todo hay que crear una base de datos con la extensión sq3 (Al final del post les dejaré una base de datos en blanco para que practiquen)
una vez que tengamos nuestra base de datos, debemos crear una tabla (Pueden ser 2, 3, depende de lo que quieran hacer)
Para crear una tabla deben usar un código similar a este
Explicaré como funciona:
Bueno, vamos a separar los factores de esta consulta, empezamos con
• CREATE TABLE = Crear tabla (Inglés básico)
• 'Nombre' = Nombre de la tabla (No son necesarias las '')
• ( y ) es similar a cualquier función en pawn
• Texto1 = Nombre de el 'array', como podemos ver va acompañado de varchar(33) NOT NULL default '' PRIMARY KEY, varchar(33) quiere decir que lo que guardaremos en ese array es texto, sería similar a new nombre[33] en pawn, NOT NULL quiere decir que se va a usar, default '' quiere decir que su valor por defecto va a ser '' y PRIMARY KEY significa que va a ser una columna única, es decir, que no se va a poder repetir, por ejemplo no se van a poder registrar 2 usuarios con el mismo nombre...
• Texto2 = Igual al Texto1 pero no es PRIMARY KEY
• Variable1 = Nombre de la 'variable', también va acompañada de otros valores, como int NOT NULL default '0', int quiere decir que va a guardar números enteros, sería similar a new variable en pawn, NOT NULL ya lo expliqué y default 0 quiere decir que su valor por defecto será 0
• Float1 = Nombre del 'float', acompañada de float, que indica que almacenará números decimales y default 0.0 que dice que su valor por defecto será 0.0
Bueno, por ahora ya sabemos cómo crear una tabla, ahora nos faltaría aprender cómo obtener datos de la tabla y como agregarle datos (Cargar/Guardar/Registrar)
Supongamos que tenemos una tabla como esta
Ahora cuando un jugador nuevo entre al servidor, necesitaremos registrarlo, es decir, agregarlo a la base de datos, para ello hacemos lo siguiente
• INSERT INTO Tabla = Insertar en 'Cuentas' ('Cuentas' es la tabla)
• (Nombre, Password) = Vamos a agregar un valor nuevo a los arrays Nombre y Password
• VALUES = Los valores que le asignaremos
• ('Nombre del jugador', 'Su contraseña') = Más que obvio
• Debo aclarar que al registrar una nueva entrada, se setea automaticamente el número de registro, es decir, la cuenta número X, y la columna que la almacena es la primer columna llamada 'rowid', por ejemplo, si sos el primero en registrarte tu rowid seria 1, si sos el segundo, rowid = 2, y así
Luego veremos cómo hacer todo esto desde un plugin, ahora que ya está registrado, cuando salga de el servidor, necesitaremos guardar las muertes de el jugador (Supongamos que murió 5 veces), para ello hacemos lo siguiente
• UPDATE Tabla = Actualizar 'Cuentas' ('Cuentas' es la tabla a actualizar)
• SET Variable a un valor = Establecer (Muertes = 5 en este caso, si hay mas variables a actualizar, se separa con comas, Muerte = 5, Frags = 10, etc)
• WHERE Variable es igual a = Donde (Nombre = 'Nombre del jugador' )
Ahora que ya guardamos sus muertes, cuando vuelva a entrar debemos setearle las muertes correspondientes, de la siguiente forma
• SELECT Valores = Seleccionar Muertes (en este caso)
• FROM Tabla = De la tabla X ('Cuentas')
• WHERE Variable es igual a = Donde (Nombre = 'Nombre del jugador')
Esta consulta retornará el valor de la variable Muertes
Tambien hay muchos mas usos y tipos de consulta en SQL, les dire los nombres para que busquen ustedes...
• ALTER TABLE 'Tabla' ADD COLUMN (Para agregar una nueva tabla)
• DELETE FROM 'Table' WHERE X='Y' (Borrar una entrada, por ejemplo un usuario)
• COLLATE NOCASE LIKE '%s' (No distinguir entre mayus y minus)
• SELECT * FROM Table WHERE Nombre LIKE '%x%' (Si el nombre contiene tal letra)
Hay mas pero no recuerdo todos...
Ahora les dejo un ejemplo en un plugin, el plugin registra al usuario y pide una contraseña, y guarda las muertes de el jugador, es algo simple, es solo para que vean como funciona, si tienen alguna duda no duden en dejarmela o alguna sugerencia
Recuerden tener el modulo sqlite activado y pones la base de datos en addons/amxmodx/data/sqlite3/acaxD
Espero que les sirva! Saludos!!
Para poder entender cómo funciona se necesitan conocimientos previos sobre pawn (nivel medio) y conocimientos sobre SQL (igual explicaré en este post) bueno empecemos
Primero explicaré cómo funciona el lenguaje SQL, no hay mucho que decir ya que es un lenguaje muy pero muy simple, es inglés básico, simplemente hay que saber cómo realizar una consulta (query) adecuadamente para poderla llevar a cabo, veamos algunos ejemplos
Primero que todo hay que crear una base de datos con la extensión sq3 (Al final del post les dejaré una base de datos en blanco para que practiquen)
una vez que tengamos nuestra base de datos, debemos crear una tabla (Pueden ser 2, 3, depende de lo que quieran hacer)
Para crear una tabla deben usar un código similar a este
Código:
CREATE TABLE 'NombreDeLaTabla' (
Nombre varchar(33) NOT NULL default '' PRIMARY KEY,
Password varchar(192) NOT NULL default ''
)
Explicaré como funciona:
Código:
CREATE TABLE 'Nombre' (Texto1 varchar(33) NOT NULL default '' PRIMARY KEY, Texto2 varchar(33) NOT NULL default '', Variable1 int NOT NULL default 0, Float1 float NOT NULL default 0.0)
Bueno, vamos a separar los factores de esta consulta, empezamos con
• CREATE TABLE = Crear tabla (Inglés básico)
• 'Nombre' = Nombre de la tabla (No son necesarias las '')
• ( y ) es similar a cualquier función en pawn
• Texto1 = Nombre de el 'array', como podemos ver va acompañado de varchar(33) NOT NULL default '' PRIMARY KEY, varchar(33) quiere decir que lo que guardaremos en ese array es texto, sería similar a new nombre[33] en pawn, NOT NULL quiere decir que se va a usar, default '' quiere decir que su valor por defecto va a ser '' y PRIMARY KEY significa que va a ser una columna única, es decir, que no se va a poder repetir, por ejemplo no se van a poder registrar 2 usuarios con el mismo nombre...
• Texto2 = Igual al Texto1 pero no es PRIMARY KEY
• Variable1 = Nombre de la 'variable', también va acompañada de otros valores, como int NOT NULL default '0', int quiere decir que va a guardar números enteros, sería similar a new variable en pawn, NOT NULL ya lo expliqué y default 0 quiere decir que su valor por defecto será 0
• Float1 = Nombre del 'float', acompañada de float, que indica que almacenará números decimales y default 0.0 que dice que su valor por defecto será 0.0
Bueno, por ahora ya sabemos cómo crear una tabla, ahora nos faltaría aprender cómo obtener datos de la tabla y como agregarle datos (Cargar/Guardar/Registrar)
Supongamos que tenemos una tabla como esta
Código:
CREATE TABLE 'Cuentas' (
Nombre varchar(33) NOT NULL default '' PRIMARY KEY,
Password varchar(192) NOT NULL default '',
Muertes int NOT NULL default 0
)
Ahora cuando un jugador nuevo entre al servidor, necesitaremos registrarlo, es decir, agregarlo a la base de datos, para ello hacemos lo siguiente
Código:
INSERT INTO 'Cuentas' (
Nombre,
Password
)
VALUES (
'Nombre del jugador',
'Su contraseña'
)
• INSERT INTO Tabla = Insertar en 'Cuentas' ('Cuentas' es la tabla)
• (Nombre, Password) = Vamos a agregar un valor nuevo a los arrays Nombre y Password
• VALUES = Los valores que le asignaremos
• ('Nombre del jugador', 'Su contraseña') = Más que obvio
• Debo aclarar que al registrar una nueva entrada, se setea automaticamente el número de registro, es decir, la cuenta número X, y la columna que la almacena es la primer columna llamada 'rowid', por ejemplo, si sos el primero en registrarte tu rowid seria 1, si sos el segundo, rowid = 2, y así
Luego veremos cómo hacer todo esto desde un plugin, ahora que ya está registrado, cuando salga de el servidor, necesitaremos guardar las muertes de el jugador (Supongamos que murió 5 veces), para ello hacemos lo siguiente
Código:
UPDATE 'Cuentas' SET
Muertes = 5
WHERE Nombre = 'Nombre del jugador'
• UPDATE Tabla = Actualizar 'Cuentas' ('Cuentas' es la tabla a actualizar)
• SET Variable a un valor = Establecer (Muertes = 5 en este caso, si hay mas variables a actualizar, se separa con comas, Muerte = 5, Frags = 10, etc)
• WHERE Variable es igual a = Donde (Nombre = 'Nombre del jugador' )
Ahora que ya guardamos sus muertes, cuando vuelva a entrar debemos setearle las muertes correspondientes, de la siguiente forma
Código:
SELECT Muertes FROM 'Cuentas'
WHERE Nombre = 'Nombre del jugador'
• SELECT Valores = Seleccionar Muertes (en este caso)
• FROM Tabla = De la tabla X ('Cuentas')
• WHERE Variable es igual a = Donde (Nombre = 'Nombre del jugador')
Esta consulta retornará el valor de la variable Muertes
Tambien hay muchos mas usos y tipos de consulta en SQL, les dire los nombres para que busquen ustedes...
• ALTER TABLE 'Tabla' ADD COLUMN (Para agregar una nueva tabla)
• DELETE FROM 'Table' WHERE X='Y' (Borrar una entrada, por ejemplo un usuario)
• COLLATE NOCASE LIKE '%s' (No distinguir entre mayus y minus)
• SELECT * FROM Table WHERE Nombre LIKE '%x%' (Si el nombre contiene tal letra)
Hay mas pero no recuerdo todos...
Ahora les dejo un ejemplo en un plugin, el plugin registra al usuario y pide una contraseña, y guarda las muertes de el jugador, es algo simple, es solo para que vean como funciona, si tienen alguna duda no duden en dejarmela o alguna sugerencia
Código PHP:
/* Script generated by Pawn Studio */
#include <amxmodx>
#include <sqlx> // Incluimos sqlite
#define PLUGIN "Tutorial SQL"
#define AUTHOR "Gonza.-*"
#define VERSION "1.0.0"
#define SQLX_DATABASE "base_de_datos"
const USER_NO_REGISTRADO = -1;
const USER_REGISTRADO = 0;
const USER_LOGEADO = 1;
new g_logeado[33] // Para saber si esta logeado o no
new g_muertes[33] // Guardado/Cargado de muertes
new Handle:g_query, Handle:g_tuple // Tupla (conección) y query (consulta)
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_message(get_user_msgid("VGUI"), "message_vgui")
register_message(get_user_msgid("DeathMsg"), "message_death")
register_clcmd("chooseteam", "show_menu_registro")
register_clcmd("jointeam", "show_menu_registro")
register_clcmd("REGISTRE_SU_PASSWORD", "REGISTRE_SU_PASSWORD")
register_clcmd("INGRESA_TU_PASSWORD", "INGRESA_TU_PASSWORD")
register_clcmd("say /muertes", "show_muertes")
register_clcmd("say_team /muertes", "show_muertes")
SQLXInit()
}
public show_muertes(id) client_print(id, print_chat, "Moriste %d %s", g_muertes[id], g_muertes[id] > 1 ? "veses" : "ves")
public REGISTRE_SU_PASSWORD(id)
{
if (g_logeado[id] != USER_NO_REGISTRADO) return
static szArg[192]; read_args(szArg, 191) // Agarramos la password que introdujo
remove_quotes(szArg); trim(szArg) // Le sacamos las comillas y los espacios del principio y final (si los tiene)
if (containi(szArg, "^"") != -1) // Prevenimos las comillas por el SQL Injection
{
client_print(id, print_center, "No puedes usar comillas")
client_cmd(id, "messagemode REGISTRE_SU_PASSWORD")
}
static szName[33]; get_user_name(id, szName, 32)
// Insertamos el nombre y la contraseña en una nueva entrada en la tabla Cuentas
g_query = SQL_PrepareQuery(g_tuple, "INSERT INTO 'Cuentas' (Nombre, Password) VALUES (^"%s^", ^"%s^")", szName, szArg)
if (SQL_Execute(g_query)) // Se realizo bien la consulta...
{
g_logeado[id] = USER_LOGEADO
client_cmd(id, "jointeam 5")
client_print(id, print_center, "Te has registrado correctamente!")
}
else client_print(id, print_center, "Error al registrarte :(")
}
public INGRESA_TU_PASSWORD(id)
{
if (g_logeado[id] != USER_REGISTRADO) return
static szArg[192]; read_args(szArg, 191) // Agarramos la password que introdujo
remove_quotes(szArg); trim(szArg) // Le sacamos las comillas y los espacios del principio y final (si los tiene)
static szName[33]; get_user_name(id, szName, 32)
// Obtenemos la contraseña y las muertes del usuario
g_query = SQL_PrepareQuery(g_tuple, "SELECT Password, Muertes FROM 'Cuentas' WHERE Nombre = ^"%s^"", szName)
if (SQL_Execute(g_query)) // Se realizo bien la consulta...
{
static szPass[192]; SQL_ReadResult(g_query, 0, szPass, 191) // Leemos la password de el usuario
if (equal(szPass, szArg)) // Si la password verdadera y la password que ingresó son iguales
{
/*
* Aca voy a explicar algo con respecto a cargar datos, si cuando cargamos datos
* la consulta es asi: SELECT Dato1, Dato2, Dato3 FROM Tabla WHERE Nombre='asd'
* el Dato1 seria SQL_ReadResult(g_query, 0)
* el Dato2 seria SQL_ReadResult(g_query, 1)
* el Dato3 seria SQL_ReadResult(g_query, 2)
* Pero si la consulta es asi: SELECT * FROM Table WHERE Nombre='asd'
* el simbolo * significa que obtendremos todos los datos de la tabla, supongamos
* que la tabla es asi: Nombre | Password | Muertes (No cuenta el rowid)
* SQL_ReadResult(g_query, 0, Nombre, len)
* SQL_ReadResult(g_query, 1, Password, len)
* Muertes = SQL_ReadResult(g_query, 2)
* En caso de querer cargar un float seria asi
* new Float:fvAngle; SQL_ReadResult(g_query, num, fvAngle)
* Con esto quiero aclarar que devuelve valores en orden segun como este creada
* la base de datos
*/
g_muertes[id] = SQL_ReadResult(g_query, 1) // Seteamos las muertes
g_logeado[id] = USER_LOGEADO
client_cmd(id, "jointeam 5")
client_print(id, print_center, "Te has logeado correctamente!")
}
else
{
client_cmd(id, "messagemode INGRESA_TU_PASSWORD")
client_print(id, print_center, "Password incorrecta")
}
}
else client_print(id, print_center, "Error al logearte :(") // Error :|
}
public show_menu_registro(id)
{
if (g_logeado[id] == USER_LOGEADO) return PLUGIN_CONTINUE;
new menu = menu_create("Menu de registro", "Handler")
menu_additem(menu, "Registrarse", _, _, menu_makecallback("callback"))
menu_additem(menu, "Logearse", _, _, menu_makecallback("callback"))
menu_setprop(menu, MPROP_EXIT, MEXIT_NEVER)
menu_display(id, menu)
return PLUGIN_HANDLED;
}
public callback(id, menu, item)
{
static szName[33], registrado; get_user_name(id, szName, 32)
// Nos fijamos si el nombre de el jugador esta registrado
g_query = SQL_PrepareQuery(g_tuple, "SELECT Nombre FROM 'Cuentas' WHERE Nombre = ^"%s^"", szName)
if (SQL_Execute(g_query)) // Se realizo bien la consulta...
{
if (SQL_NumResults(g_query)) registrado = 1, g_logeado[id] = USER_REGISTRADO
else registrado = 0
}
else registrado = -1
switch (item)
{
case 0: if (registrado || registrado == -1) return ITEM_DISABLED; // Si esta registrado no puede apretar el item 1 (Registrarse)
case 1: if (!registrado || registrado == -1) return ITEM_DISABLED; // Si no esta registrado no puede apretar el item 2 (Logearse)
}
return ITEM_ENABLED; // Puede apretar el item correspondiente
}
public Handler(id, menu, item)
{
switch (item)
{
case 0:
{
client_cmd(id, "messagemode REGISTRE_SU_PASSWORD")
client_print(id, print_center, "Elije una password para tu cuenta")
}
case 1:
{
client_cmd(id, "messagemode INGRESA_TU_PASSWORD")
client_print(id, print_center, "Ingresa la password de tu cuenta")
}
}
menu_destroy(menu)
return PLUGIN_HANDLED;
}
public message_vgui(msg_id, dest, msg_ent)
{
if (g_logeado[msg_ent] == USER_LOGEADO) return PLUGIN_CONTINUE // Si esta logeado...
show_menu_registro(msg_ent) // Mostramos el menu para que se registre o logee
return PLUGIN_HANDLED
}
public message_death(msg_id, dest, msg_ent)
{
static victim; victim = get_msg_arg_int(2)
if (is_user_connected(victim)) // No se si es nesesario, pero por las dudas
{
g_muertes[victim]++ // Sumamos una muerte
Guardar(victim) // Guardamos
}
}
public client_putinserver(id)
{
client_cmd(id, "setinfo _vgui_menus 1") // Para prevenir bugs con el menu de join team
g_logeado[id] = USER_NO_REGISTRADO
g_muertes[id] = 0
}
public client_disconnect(id) Guardar(id)
public Guardar(id)
{
if (g_logeado[id] != USER_LOGEADO) return // Si no esta logeado...
static szName[33]; get_user_name(id, szName, 32)
// Seteamos las nuevas muertes
g_query = SQL_PrepareQuery(g_tuple, "UPDATE 'Cuentas' SET Muertes = %d WHERE Nombre = ^"%s^"", g_muertes[id], szName)
SQL_Execute(g_query) // Ejecutamos la consulta para asi guardar los nuevos datos
}
public CheckTabla()
{
// Creamos la tabla si no existe
g_query = SQL_PrepareQuery(g_tuple, "CREATE TABLE IF NOT EXISTS 'Cuentas' (Nombre varchar(33) NOT NULL default '' PRIMARY KEY, Password varchar(192) NOT NULL default '', Muertes int NOT NULL default 0)")
SQL_Execute(g_query)
}
public SQLXInit()
{
new get_type[12]
SQL_SetAffinity("sqlite") // Seteamos el driver correcto
SQL_GetAffinity(get_type, sizeof(get_type)) // Obtenemos el driver actual
if (!equali(get_type, "sqlite")) // Si el driver no es el driver correspondiente a sqlite
{
log_to_file("SQLX.log", "Driver no encontrado") // Avisamos a traves de un log
pause("a") // Pausamos el plugin
}
else
{
static error, szError[300]
// Creamos la conección
g_query = SQL_MakeDbTuple("", "", "", SQLX_DATABASE)
g_tuple = SQL_Connect(g_query, error, szError, 300)
if (strlen(szError))
{
log_to_file("ErrorSQL.log", szError)
pause("a")
}
CheckTabla()
}
}
public plugin_end() SQL_FreeHandle(g_tuple) // Liberamos la conección
Recuerden tener el modulo sqlite activado y pones la base de datos en addons/amxmodx/data/sqlite3/acaxD
Espero que les sirva! Saludos!!