При разработке нового проекта иногда встаёт вопрос об упрощении работы со структурами данных, таких как аккаунты, транспорт, недвижимость и т.п. Одним из вариантов является перевод сервера на базы данных. Из коробки SAMP предлагает использовать SQLite, но в данной статье мы рассмотрим MySQL. Для начала необходимо определиться с версией и автором плагина СУБД, который вы хотите использовать. Советую брать самую актуальную и свежую версию. На сегодняшний момент это
ВНИМАНИЕ: дальнейшая инструкция актуальна только для рассматриваемой версии плагина. Работа в любой другой версии не гарантируется, т.к. меняются названия функций, порядок параметров и т.п.
Установка простая:
В конфигурационном файле (server.cfg) прописываем:
или добавляем в строку с уже имеющимися у вас плагинами.
Теперь в моде можно (хотя и не обязательно) указать данные для доступа к базе данных в виде дефайнов:
Как устанавливать phpmyadmin мы рассматривали в прошлом FAQ, поэтому скажу лишь, что при установке MySQL и PHPMyAdmin в списке баз данных появляются внутренние:
* PERFORMANCE_SCHEMA - обеспечивает способ осмотреть внутреннее выполнение сервера во времени выполнения.
* INFORMATION_SCHEMA - обеспечивает доступ к метаданным базы данных.
И ещё пара: phpmyadmin с настройками надстройки, а также mysql со служебными настройками баз данных в целом.
ВНИМАНИЕ: Если вы не видите служебные базы данных в списке, то для текущего пользователя недостаточно прав доступа, подключитесь под root.
ВНИМАНИЕ: Если вы каким-то образом накосячили и ваши шаловливые ручки почикали системные БД, то не всё потеряно. Команда mysql_upgrade (через PuTTY) восстановит базу данных performance_schema:
Далее я буду рассматривать усложнённые варианты работы с базой данных, а через phpmyadmin будем только проверять результат. Метод этот был разработан для одного проекта. Он позволяет не иметь дамп базы данных для запуска сервера. Не хотел публиковать этот мануал, оставив в кулуарах соответствующих междусобойчиков, но попросил тот, кому нельзя отказать )))
Итак, после дефайнов по данным нашей базы данных (вводим туда свои, полученные при покупке хостинга), в OnGameModeInit пишем следующий код.
Далее нужно создать структуру таблиц, которыми мы будем пользоваться.
Ниже принтов о подключении к БД пишем:
Далее введём ещё один дефайн, от которого часто подгорают пуканы хейтеров. Никакие там пабликсы или фпаблики делать не нужно - это бред. У нас есть отличное зарезервированное слово VOID. Да, все, кто связан с другими языками программирования, знают, что оно означает, но поскольку в PAWN оно не используется, но подсвечивается, будем использовать именно его. Потому что я так сказал)
Далее расписываем ответ запроса по фракциям:
То же самое делаем с таблицей игроков. Тут покажу второй метод разделения запросов (по пабликам):
Пока остановимся на этих таблицах. Далее рассмотрим реакцию на вход игрока. В OnPlayerConnect:
Проверяем пароль и разбан:
Загрузка акка:
Если при регистрации вы сразу пишете данные в БД, как я, то если игрок вышел, не завершив регистрацию, нужно удалить соответствующие данные:
И обработка запроса:
Через PHPMyAdmin можно отслеживать этапы обработки запросов, что я категорически рекомендую. При ошибках в запросах читаем mysql_log.txt в директории с сервером и исправляем ошибки.
P.S. Для блондинок по жизни, да и брюнеток, которые просто хотят быть уверены в правильности своих действий, полный листинг кода я закинул под спойлер.
ВНИМАНИЕ: данный код не является работоспособной регистрацией, а только показывает порядок работы с базой данных
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
от BlueG. Этот плагин можно назвать "лорным", т.к. автором является один из бета-тестеров SA-MP, инклюд по названию схож с остальными САМПовскими, поддерживается и обновляется практически до сих пор.
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
ВНИМАНИЕ: дальнейшая инструкция актуальна только для рассматриваемой версии плагина. Работа в любой другой версии не гарантируется, т.к. меняются названия функций, порядок параметров и т.п.
Установка простая:
- Файл a_mysql.inc кладём в папку pawno/includes/
- Файл mysql.so/.dll кладём в папку plugins/
- Файл log-core.so/.dll кладём в корневую папку сервера.
- Файл libmariadb.dll кладём в корневую папку сервера*.
В конфигурационном файле (server.cfg) прописываем:
PHP:
plugins mysql.so
Теперь в моде можно (хотя и не обязательно) указать данные для доступа к базе данных в виде дефайнов:
PHP:
#define SQL_HOST "localhost"
#define SQL_USER "пользователь_базы_данных"
#define SQL_DB "имя_базы_данных"
#define SQL_PASS "пароль_пользователя_базы_данных"
* PERFORMANCE_SCHEMA - обеспечивает способ осмотреть внутреннее выполнение сервера во времени выполнения.
* INFORMATION_SCHEMA - обеспечивает доступ к метаданным базы данных.
И ещё пара: phpmyadmin с настройками надстройки, а также mysql со служебными настройками баз данных в целом.
ВНИМАНИЕ: Если вы не видите служебные базы данных в списке, то для текущего пользователя недостаточно прав доступа, подключитесь под root.
ВНИМАНИЕ: Если вы каким-то образом накосячили и ваши шаловливые ручки почикали системные БД, то не всё потеряно. Команда mysql_upgrade (через PuTTY) восстановит базу данных performance_schema:
Код:
mysql_upgrade --user=root --password=password // или после равно пусто, если не ставили пароль root'у
Итак, после дефайнов по данным нашей базы данных (вводим туда свои, полученные при покупке хостинга), в OnGameModeInit пишем следующий код.
PHP:
new MySQL:SQL_HANDLE; // наш ID подключения, пригодится в запросах
public OnGameModeInit()
{
SQL_HANDLE = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS, "MySQL"); // подключаемся к служебной базе данных mysql (регистр букв значения не имеет, по крайней мере на Windows, так что рекомендую писать так, как есть на самом деле, т.е.: mysql, а не как тут)
mysql_query(SQL_HANDLE, "CREATE DATABASE IF NOT EXISTS "SQL_DB); // запрос создаёт нашу базу данных, если её не существовало ранее (запомните про это условие, потом поймёте почему)
mysql_close(SQL_HANDLE); // отключаемся от служебной базы данных
SQL_HANDLE = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS, SQL_DB); // соединяемся с только что созданной базой данных
mysql_log(); // включаем логи работы с базой, а далее проверяем доступность соединения
if(!mysql_errno()) print(!"Подключение к базе данных MySQL успешно создано!");
else print(!"Невозможно подключиться к базе данных MySQL!");
return 1;
}
Ниже принтов о подключении к БД пишем:
PHP:
mysql_tquery(SQL_HANDLE, !"SHOW TABLES LIKE 'factions'", !"OnFactionsTableExist", ""); // запрос покажет таблицы с названием factions в отдельном паблике
mysql_tquery(SQL_HANDLE, !"SHOW TABLES LIKE 'players'", !"OnPlayersTableExist", ""); // запрос покажет таблицу с названием players в отдельном паблике
PHP:
#define void%0(%1) forward %0(%1); public %0(%1)
PHP:
void OnFactionsTableExist()
{
new rows;
if(!cache_get_row_count(rows)) // если в ответе на запрос не вернулось строк с ответом, т.е. таблицы не существует
{
mysql_tquery(SQL_HANDLE,
"CREATE TABLE IF NOT EXISTS `factions`(\
`ID` int(10) NOT NULL AUTO_INCREMENT, \
`FactionName` varchar(32) NOT NULL, \
`FColor` int(11) NOT NULL, \
`FRank1` varchar(12) NOT NULL, \
`FRank2` varchar(12) NOT NULL, \
`FRank3` varchar(12) NOT NULL, \
`FRank4` varchar(12) NOT NULL, \
`FRank5` varchar(12) NOT NULL, \
`FRank6` varchar(12) NOT NULL, \
`FRank7` varchar(12) NOT NULL, \
`FRank8` varchar(12) NOT NULL, \
`FRank9` varchar(12) NOT NULL, \
`FRank10` varchar(12) NOT NULL, \
PRIMARY KEY (`ID`))",
"", ""); // создаём структуру по вашему enum для фракций
mysql_tquery(SQL_HANDLE, "ALTER TABLE `factions`(\
`FRank11` varchar(12) NOT NULL, \
`FRank12` varchar(12) NOT NULL",
"", ""); // если компилятор старый, и длина строки не позволяет писать всё в одном запросе, делить можно так, поскольку ALTER добавляет столбцы в таблице
for(new i = 0; i < MAX_FACTIONS; i++)
{
Info_Faction[i][fName][0] = EOS; // мой enum по фракциям
strcat(Info_Faction[i][fName], Names_Faction[i], 24);
Info_Faction[i][fColor] = Colors_Faction[i]; // массив с цветами фракций
mysql_tquery(SQL_HANDLE, "INSERT IGNORE INTO `factions` \
(`FactionName`, `FColor`, `FRank1`, `FRank2`, `FRank3`, `FRank4`, `FRank5`, `FRank6`, `FRank7`, `FRank8`, `FRank9`, `FRank10`, `FRank11`, `FRank12`) VALUES \
('%e', '%d', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e')",
Info_Faction[i][fName], Info_Faction[i][fColor],
Info_Faction[i][fRank1], Info_Faction[i][fRank2], Info_Faction[i][fRank3], Info_Faction[i][fRank4], Info_Faction[i][fRank5], Info_Faction[i][fRank6],
Info_Faction[i][fRank7], Info_Faction[i][fRank8], Info_Faction[i][fRank9], Info_Faction[i][fRank10], Info_Faction[i][fRank11], Info_Faction[i][fRank12]
); // заполняем базу данных данными из массивов, прописанных в моде
}
return 1;
}
return 1;
}
PHP:
void OnPlayersTableExist()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE,
"CREATE TABLE IF NOT EXISTS `players`(\
`ID` int(10) NOT NULL AUTO_INCREMENT, \
`Username` varchar(24) NOT NULL, \
`Password` varchar(65) NOT NULL, \
`Email` varchar(128) NOT NULL, \
`Birth` varchar(12) NOT NULL, \
`RegDate` varchar(12) NOT NULL, \
`History` int(5) NOT NULL, \
`Sex` int(5) NOT NULL, \
`Country` int(5) NOT NULL, \
`Skin` int(5) NOT NULL, \
`Level` int(5) NOT NULL, \
`Exp` int(5) NOT NULL, \
`Admin` int(5) NOT NULL, \
`Interior` int(3) NOT NULL, \
PRIMARY KEY (`ID`))",
!"OnDataBaseCreateEnd", "");
return 1;
}
return 1;
}
void OnDataBaseCreateEnd()
{
new rows;
if(!cache_get_row_count(rows)) // я думаю это условие можно убрать, т.к. возврат строк был только для главного запроса в OnGameModeInit
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `VirtualWorld` int(6) NOT NULL, \
ADD `PosX` float NOT NULL, \
ADD `PosY` float NOT NULL, \
ADD `PosZ` float NOT NULL, \
ADD `PosA` float NOT NULL, \
ADD `Color` int(6) NOT NULL, \
ADD `PddTest` float NOT NULL, \
ADD `DrvNum` float NOT NULL, \
ADD `DrvDateA` varchar(12) NOT NULL, \
ADD `DrvDateB` varchar(12) NOT NULL, \
ADD `DrvDateC` varchar(12) NOT NULL, \
ADD `DrvDateD` varchar(12) NOT NULL, \
ADD `DrvDateF` varchar(12) NOT NULL",
!"OnDataBaseCreateEnd2", "");
}
return 1;
}
void OnDataBaseCreateEnd2()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `LicA` int(2) NOT NULL, \
ADD `LicB` int(2) NOT NULL, \
ADD `LicC` int(2) NOT NULL, \
ADD `LicD` int(2) NOT NULL, \
ADD `LicF` int(2) NOT NULL, \
ADD `Faction` int(2) NOT NULL, \
ADD `InvDate` varchar(12) NOT NULL, \
ADD `Rank` int(2) NOT NULL, \
ADD `Pass` int(2) NOT NULL, \
ADD `Work` int(2) NOT NULL, \
ADD `Warn` int(2) NOT NULL, \
ADD `UnMuteTime` int(2) NOT NULL, \
ADD `UnBanTime` int(2) NOT NULL, \
ADD `SDPistol` int(2) NOT NULL",
!"OnDataBaseCreateEnd3", "");
}
return 1;
}
void OnDataBaseCreateEnd3()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `Deagle` int(2) NOT NULL, \
ADD `Shotgun` int(2) NOT NULL, \
ADD `MP5` int(2) NOT NULL, \
ADD `AK47` int(2) NOT NULL, \
ADD `M4A1` int(2) NOT NULL, \
ADD `Money` int(2) NOT NULL, \
ADD `Law` int(2) NOT NULL, \
ADD `Wanted` int(2) NOT NULL, \
ADD `Spouse` varchar(24) NOT NULL, \
ADD `Bank` int(2) NOT NULL, \
ADD `House` int(2) NOT NULL, \
ADD `Biz` int(2) NOT NULL, \
ADD `Flat` int(2) NOT NULL, \
ADD `Room` int(2) NOT NULL, \
ADD `BankAccount` int(2) NOT NULL",
!"OnDataBaseCreateEnd4", "");
}
return 1;
}
void OnDataBaseCreateEnd4()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `Hunger` int(2) NOT NULL, \
ADD `Piss` int(2) NOT NULL, \
ADD `Hygiene` int(2) NOT NULL",
"", "");
}
return 1;
} // закончили создание параметров аккаунта
PHP:
mysql_format(SQL_HANDLE, query, sizeof(query), "SELECT `Password`, `UnBanTime` FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]); // берём пароль, время разбана
mysql_tquery(SQL_HANDLE, query, !"OnPlayerEnter", "i", playerid);
PHP:
void OnPlayerEnter(playerid)
{
new rows;
if(!cache_get_row_count(rows)) // если аккаунта нет
{
/*
// рега
mysql_format(SQL_HANDLE, query, sizeof(query), "INSERT IGNORE INTO `players` (`Username`, `Password`, `Email`, `Birth`, `RegDate`, `History`, `Skin`, `Level`, `Admin`, `Sex`, `Faction`, `Rank`) VALUES ('%e', '%e', '%e', '%e', '%02d/%02d/%04d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
Info_User[playerid][uName],
password,
email,
birth,
day,
month,
year,
GetPVarInt(playerid, !"History"),
GetPVarInt(playerid, !"Skin"),
GetPVarInt(playerid, !"Level"),
GetPVarInt(playerid, !"Admin"),
GetPVarInt(playerid, !"Sex"),
GetPVarInt(playerid, !"Faction"),
GetPVarInt(playerid, !"Rank")
);
mysql_tquery(SQL_HANDLE, query, "", ""); // вставляем в БД необходимые данные для создания аккаунта
*/
}
else
{
new btime;
cache_get_value_name_int(0, !"UnBanTime", btime);
if(btime > gettime()) return Kick(playerid); // если время разбана не подошло - кикаем
mysql_format(SQL_HANDLE, query, sizeof(query), "SELECT * FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, !"OnPlayerDataLoaded", "i", playerid);
}
}
PHP:
void OnPlayerDataLoaded(playerid)
{
new skin; cache_get_value_name_int(0, !"Skin", skin); SetPVarInt(playerid, !"Skin", skin); SetPlayerSkin(playerid, GetPVarInt(playerid, !"Skin"));
new sex; cache_get_value_name_int(0, !"Sex", sex); SetPVarInt(playerid, !"Sex", sex);
new admin; cache_get_value_name_int(0, !"Admin", admin); SetPVarInt(playerid, !"Admin", admin);
new faction; cache_get_value_name_int(0, !"Faction", faction); SetPVarInt(playerid, !"Faction", faction);
new rank; cache_get_value_name_int(0, !"Rank", rank); SetPVarInt(playerid, !"Rank", rank);
new pass; cache_get_value_name_int(0, !"Pass", pass); SetPVarInt(playerid, !"Pass", pass);
new work; cache_get_value_name_int(0, !"Work", work); SetPVarInt(playerid, !"Work", work);
new law; cache_get_value_name_int(0, !"Law", law); SetPVarInt(playerid, !"Law", law);
new wanted; cache_get_value_name_int(0, !"Wanted", wanted); SetPVarInt(playerid, !"Wanted", wanted);
new warn; cache_get_value_name_int(0, !"Warn", warn); SetPVarInt(playerid, !"Warn", warn);
new unmutetime; cache_get_value_name_int(0, !"UnMuteTime", unmutetime); SetPVarInt(playerid, !"UnMuteTime", unmutetime);
new unbantime; cache_get_value_name_int(0, !"UnBanTime", unbantime); SetPVarInt(playerid, !"UnBanTime", unbantime);
new hunger; cache_get_value_name_int(0, !"Hunger", hunger); SetPVarInt(playerid, !"Hunger", hunger);
// и т.д.
// Text
new spouse[MAX_PLAYER_NAME];
cache_get_value_name(0, !"Spouse", spouse, sizeof(spouse));
SetPVarString(playerid, !"Spouse", spouse);
new regdate[12];
cache_get_value_name(0, !"RegDate", regdate, sizeof(regdate));
SetPVarString(playerid, !"RegDate", regdate);
new birth[12];
cache_get_value_name(0, !"Birth", birth, sizeof(birth));
SetPVarString(playerid, !"Birth", birth);
return 1;
}
PHP:
public OnPlayerDisconnect(playerid, reason)
{
if(!GetPVarInt(playerid, !"Spawned")) // если не закончил регу
{
mysql_format(SQL_HANDLE, query, sizeof(query), "SELECT `Country` FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]); // если страна не указана - рега не закончена
mysql_tquery(SQL_HANDLE, query, !"OnPlayerNotComplete", "i", playerid);
ResetPlayerParams(playerid); // обнуляем pInfo, потому что PVar'ы вам, видите ли, не нравятся (а у меня там только имя, лол, ахахах)
return 1;
}
new Float:x, Float:y, Float:z, Float:a;
GetPlayerPos(playerid, x, y, z);
GetPlayerFacingAngle(playerid, a);
mysql_format(SQL_HANDLE, query, sizeof(query), "UPDATE `players` SET `Interior` = '%d', `VirtualWorld` = '%d', `PosX` = '%.4f', `PosY` = '%0.4f', `PosZ` = '%0.4f', `PosA` = '%0.3f' WHERE `Username` = '%e'", GetPlayerInterior(playerid), GetPlayerVirtualWorld(playerid), x, y, z, a, Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, "", ""); // обновляем место последнего положения для спавна на нём при следующем входе
ResetPlayerParams(playerid); // обнуляем pInfo ваши любимые, супер-оптимизированные
return 1;
}
PHP:
void OnPlayerNotComplete(playerid)
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_format(SQL_HANDLE, query, sizeof(query), "DELETE FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, "", "");
ResetPlayerParams(playerid); // тут обнуляется pInfo
return 1;
}
return 1;
}
P.S. Для блондинок по жизни, да и брюнеток, которые просто хотят быть уверены в правильности своих действий, полный листинг кода я закинул под спойлер.
ВНИМАНИЕ: данный код не является работоспособной регистрацией, а только показывает порядок работы с базой данных
PHP:
#define SQL_HOST "localhost"
#define SQL_USER "root"
#define SQL_DB "weiland"
#define SQL_PASS ""
#define void%0(%1) forward %0(%1); public %0(%1)
#define MAX_FACTIONS 10
new MySQL:SQL_HANDLE;
enum uData
{
uName[MAX_PLAYER_NAME],
uDrvDateA[12],
uDrvDateB[12],
uDrvDateC[12],
uDrvDateD[12],
uDrvDateF[12]
};
new Info_User[MAX_PLAYERS][uData];
enum fData
{
fName[32],
fColor,
fRank1[12],
fRank2[12],
fRank3[12],
fRank4[12],
fRank5[12],
fRank6[12],
fRank7[12],
fRank8[12],
fRank9[12],
fRank10[12],
fRank11[12],
fRank12[12]
};
new Info_Faction[MAX_FACTIONS][fData];
new Names_Faction[MAX_FACTIONS][24] = {!"Фракция 1", !"Фракция 2", !"Автошкола", !"Армия", !"ЛСПД", !"Фракция 6", !"Фракция 7", !"Фракция 8", !"Фракция 9", !"Фракция 10"};
new Colors_Faction[MAX_FACTIONS] = {0xFFFFFFAA, 0xFFFFFFAA, 0x3366FFAA, 0x006600AA, 0xFFFFFFAA, 0xFFFFFFAA, 0xFFFFFFAA, 0xFFFFFFAA, 0xFFFFFFAA, 0xFFFFFFAA};
static query[2048];
public OnGameModeInit()
{
SQL_HANDLE = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS, "MySQL");
mysql_tquery(SQL_HANDLE, "CREATE DATABASE IF NOT EXISTS"SQL_DB, "", "");
mysql_close(SQL_HANDLE);
SQL_HANDLE = mysql_connect(SQL_HOST, SQL_USER, SQL_PASS, SQL_DB);
mysql_log();
if(!mysql_errno()) print(!"Подключение к базе данных MySQL успешно создано!");
else print(!"Невозможно подключиться к базе данных MySQL!");
mysql_tquery(SQL_HANDLE, !"SHOW TABLES LIKE 'factions'", !"OnFactionsTableExist", "");
mysql_tquery(SQL_HANDLE, !"SHOW TABLES LIKE 'players'", !"OnPlayersTableExist", "");
strcat(Info_Faction[0][fName], !"Отсутствует", 32);
return 1;
}
public OnPlayerConnect(playerid)
{
GetPlayerName(playerid, Info_User[playerid][uName], MAX_PLAYER_NAME);
// # Account
mysql_format(SQL_HANDLE, query, sizeof(query), "SELECT `Password`, `UnBanTime` FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, !"OnPlayerEnter", "i", playerid);
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
if(!GetPVarInt(playerid, !"Spawned"))
{
mysql_format(SQL_HANDLE, query, sizeof(query), "SELECT `Country` FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, !"OnPlayerNotComplete", "i", playerid);
ResetPlayerParams(playerid);
return 1;
}
new Float:x, Float:y, Float:z, Float:a;
GetPlayerPos(playerid, x, y, z);
GetPlayerFacingAngle(playerid, a);
mysql_format(SQL_HANDLE, query, sizeof(query), "UPDATE `players` SET `Interior` = '%d', `VirtualWorld` = '%d', `PosX` = '%.4f', `PosY` = '%0.4f', `PosZ` = '%0.4f', `PosA` = '%0.3f' WHERE `Username` = '%e'", GetPlayerInterior(playerid), GetPlayerVirtualWorld(playerid), x, y, z, a, Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, "", "");
ResetPlayerParams(playerid);
return 1;
}
stock ResetPlayerParams(playerid)
{
Info_User[playerid][uName][0] = EOS;
return 1;
}
// MySQL Func
void OnFactionsTableExist()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE,
"CREATE TABLE IF NOT EXISTS `factions`(\
`ID` int(10) NOT NULL AUTO_INCREMENT, \
`FactionName` varchar(32) NOT NULL, \
`FColor` int(11) NOT NULL, \
`FRank1` varchar(12) NOT NULL, \
`FRank2` varchar(12) NOT NULL, \
`FRank3` varchar(12) NOT NULL, \
`FRank4` varchar(12) NOT NULL, \
`FRank5` varchar(12) NOT NULL, \
`FRank6` varchar(12) NOT NULL, \
`FRank7` varchar(12) NOT NULL, \
`FRank8` varchar(12) NOT NULL, \
`FRank9` varchar(12) NOT NULL, \
`FRank10` varchar(12) NOT NULL, \
PRIMARY KEY (`ID`))",
"", "");
mysql_tquery(SQL_HANDLE, "ALTER TABLE `factions`(\
`FRank11` varchar(12) NOT NULL, \
`FRank12` varchar(12) NOT NULL",
"", "");
for(new i = 0; i < MAX_FACTIONS; i++)
{
Info_Faction[i][fName][0] = EOS;
strcat(Info_Faction[i][fName], Names_Faction[i], 24);
Info_Faction[i][fColor] = Colors_Faction[i];
mysql_tquery(SQL_HANDLE, "INSERT IGNORE INTO `factions` \
(`FactionName`, `FColor`, `FRank1`, `FRank2`, `FRank3`, `FRank4`, `FRank5`, `FRank6`, `FRank7`, `FRank8`, `FRank9`, `FRank10`, `FRank11`, `FRank12`) VALUES \
('%e', '%d', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e', '%e')",
Info_Faction[i][fName], Info_Faction[i][fColor],
Info_Faction[i][fRank1], Info_Faction[i][fRank2], Info_Faction[i][fRank3], Info_Faction[i][fRank4], Info_Faction[i][fRank5], Info_Faction[i][fRank6],
Info_Faction[i][fRank7], Info_Faction[i][fRank8], Info_Faction[i][fRank9], Info_Faction[i][fRank10], Info_Faction[i][fRank11], Info_Faction[i][fRank12]
);
}
return 1;
}
return 1;
}
void OnPlayersTableExist()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE,
"CREATE TABLE IF NOT EXISTS `players`(\
`ID` int(10) NOT NULL AUTO_INCREMENT, \
`Username` varchar(24) NOT NULL, \
`Password` varchar(65) NOT NULL, \
`Email` varchar(128) NOT NULL, \
`Birth` varchar(12) NOT NULL, \
`RegDate` varchar(12) NOT NULL, \
`History` int(5) NOT NULL, \
`Sex` int(5) NOT NULL, \
`Country` int(5) NOT NULL, \
`Skin` int(5) NOT NULL, \
`Level` int(5) NOT NULL, \
`Exp` int(5) NOT NULL, \
`Admin` int(5) NOT NULL, \
`Interior` int(3) NOT NULL, \
PRIMARY KEY (`ID`))",
!"OnDataBaseCreateEnd", "");
return 1;
}
return 1;
}
void OnDataBaseCreateEnd()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `VirtualWorld` int(6) NOT NULL, \
ADD `PosX` float NOT NULL, \
ADD `PosY` float NOT NULL, \
ADD `PosZ` float NOT NULL, \
ADD `PosA` float NOT NULL, \
ADD `PddTest` float NOT NULL, \
ADD `DrvNum` float NOT NULL, \
ADD `DrvDateA` varchar(12) NOT NULL, \
ADD `DrvDateB` varchar(12) NOT NULL, \
ADD `DrvDateC` varchar(12) NOT NULL, \
ADD `DrvDateD` varchar(12) NOT NULL, \
ADD `DrvDateF` varchar(12) NOT NULL",
!"OnDataBaseCreateEnd2", "");
}
return 1;
}
void OnDataBaseCreateEnd2()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `LicA` int(2) NOT NULL, \
ADD `LicB` int(2) NOT NULL, \
ADD `LicC` int(2) NOT NULL, \
ADD `LicD` int(2) NOT NULL, \
ADD `LicF` int(2) NOT NULL, \
ADD `Faction` int(2) NOT NULL, \
ADD `InvDate` varchar(12) NOT NULL, \
ADD `Rank` int(2) NOT NULL, \
ADD `Pass` int(2) NOT NULL, \
ADD `Work` int(2) NOT NULL, \
ADD `Warn` int(2) NOT NULL, \
ADD `UnMuteTime` int(2) NOT NULL, \
ADD `UnBanTime` int(2) NOT NULL, \
ADD `SDPistol` int(2) NOT NULL",
!"OnDataBaseCreateEnd3", "");
}
return 1;
}
void OnDataBaseCreateEnd3()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `Deagle` int(2) NOT NULL, \
ADD `Shotgun` int(2) NOT NULL, \
ADD `MP5` int(2) NOT NULL, \
ADD `AK47` int(2) NOT NULL, \
ADD `M4A1` int(2) NOT NULL, \
ADD `Money` int(2) NOT NULL, \
ADD `Law` int(2) NOT NULL, \
ADD `Wanted` int(2) NOT NULL, \
ADD `Spouse` varchar(24) NOT NULL, \
ADD `Bank` int(2) NOT NULL, \
ADD `House` int(2) NOT NULL, \
ADD `Biz` int(2) NOT NULL, \
ADD `Flat` int(2) NOT NULL, \
ADD `Room` int(2) NOT NULL, \
ADD `BankAccount` int(2) NOT NULL",
!"OnDataBaseCreateEnd4", "");
}
return 1;
}
void OnDataBaseCreateEnd4()
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_tquery(SQL_HANDLE, "ALTER TABLE `players` \
ADD `Hunger` int(2) NOT NULL, \
ADD `Piss` int(2) NOT NULL, \
ADD `Hygiene` int(2) NOT NULL",
"", "");
}
return 1;
}
void OnPlayerNotComplete(playerid)
{
new rows;
if(!cache_get_row_count(rows))
{
mysql_format(SQL_HANDLE, query, sizeof(query), "DELETE FROM `players` WHERE `Username` = '%e' LIMIT 1", Info_User[playerid][uName]);
mysql_tquery(SQL_HANDLE, query, "", "");
ResetPlayerParams(playerid);
return 1;
}
return 1;
}
void OnPlayerEnter(playerid)
{
new rows;
if(!cache_get_row_count(rows))
{
// регистрация
return 1;
}
else
{
new btime;
cache_get_value_name_int(0, !"UnBanTime", btime);
if(btime > gettime()) return Kick(playerid);
// логин
}
return 1;
}
void OnPlayerDataLoaded(playerid)
{
new skin; cache_get_value_name_int(0, !"Skin", skin); SetPVarInt(playerid, !"Skin", skin); SetPlayerSkin(playerid, GetPVarInt(playerid, !"Skin"));
new sex; cache_get_value_name_int(0, !"Sex", sex); SetPVarInt(playerid, !"Sex", sex);
new admin; cache_get_value_name_int(0, !"Admin", admin); SetPVarInt(playerid, !"Admin", admin);
new faction; cache_get_value_name_int(0, !"Faction", faction); SetPVarInt(playerid, !"Faction", faction);
new rank; cache_get_value_name_int(0, !"Rank", rank); SetPVarInt(playerid, !"Rank", rank);
new pass; cache_get_value_name_int(0, !"Pass", pass); SetPVarInt(playerid, !"Pass", pass);
new work; cache_get_value_name_int(0, !"Work", work); SetPVarInt(playerid, !"Work", work);
new law; cache_get_value_name_int(0, !"Law", law); SetPVarInt(playerid, !"Law", law);
new wanted; cache_get_value_name_int(0, !"Wanted", wanted); SetPVarInt(playerid, !"Wanted", wanted);
new warn; cache_get_value_name_int(0, !"Warn", warn); SetPVarInt(playerid, !"Warn", warn);
new unmutetime; cache_get_value_name_int(0, !"UnMuteTime", unmutetime); SetPVarInt(playerid, !"UnMuteTime", unmutetime);
new unbantime; cache_get_value_name_int(0, !"UnBanTime", unbantime); SetPVarInt(playerid, !"UnBanTime", unbantime);
new hunger; cache_get_value_name_int(0, !"Hunger", hunger); SetPVarInt(playerid, !"Hunger", hunger);
// и т.д.
// Text
new spouse[MAX_PLAYER_NAME];
cache_get_value_name(0, !"Spouse", spouse, sizeof(spouse));
SetPVarString(playerid, !"Spouse", spouse);
new regdate[12];
cache_get_value_name(0, !"RegDate", regdate, sizeof(regdate));
SetPVarString(playerid, !"RegDate", regdate);
new birth[12];
cache_get_value_name(0, !"Birth", birth, sizeof(birth));
SetPVarString(playerid, !"Birth", birth);
return 1;
}