6. Создание простой системы аккаунтов
Теперь мы знаем все необходимое для создания системы аккаунтов, приступим к делу:
Пусть у нас есть таблица:
CREATE TABLE players (name varchar, pass varchar, level int, money int)
Она ОТЛИЧАЕТСЯ от той, которую мы рассмотрели в пункте 5 !!!
Не забываем про глобальные переменные:
PHP код:
new DB:ServerDB;
#define DBNAME "MyDATA.db"
И про подключение к базе в OnGameModInit:
PHP код:
public OnGameModeInit()
{
if(fexist(DBNAME)) // файл базы данных на месте
{
ServerDB = db_open(DBNAME); // просто открываем
}
else // нет файла базы данных!
{
ServerDB = db_open(DBNAME); // создаем файл базы данных ...
db_query(ServerDB, "CREATE TABLE players (name varchar, pass varchar, level int, money int)");
}
// продолжение паблика OnGameModeInit
return 1;
}
6.1 Подключение игрока к серверу
Для начала нам потребуется набор глобальных переменных, для хранения информации о игроке:
PHP код:
enum pl_info {
P_reg,
P_name[32],
P_pass[32],
P_level,
P_money
}
new PlayerInfo[MAX_PLAYERS][pl_info];
Паблик OnPlayerConnect:
PHP код:
public OnPlayerConnect(playerid)
{
PlayerInfo[playerid][P_reg] = 0; // еще не залогинился
new DBResult:RESCONN; // результат запроса
new query[128]; // переменая для строки запроса
GetPlayerName(playerid, PlayerInfo[playerid][P_name], 32); // получаем имя игрока
format(query,sizeof(query),"SELECT * FROM players WHERE name = '%s' LIMIT 1", PlayerInfo[playerid][P_name]);
// запросили данные игрока
RESCONN = db_query(ServerDB,query); // отправляем запрос
if(!db_num_rows(RESCONN)) // если имени игрока нет в таблице
{
format(query,sizeof(query),"Привет, %s!\nСначала зарегистрируйся!\nВведи свой пароль ниже:",PlayerInfo[playerid][P_name]);
ShowPlayerDialog(playerid, 51, 1, "REGISTER", query, "Далее", "Выход"); // отправили диалог с ИД 51
}
else // а если есть
{
new var[32];
db_get_field(RESCONN, 1, PlayerInfo[playerid][P_pass], 32); // вытащили пароль игрока из таблицы
db_get_field(RESCONN, 2, var, 32); PlayerInfo[playerid][P_level] = strval(var); // вытащили уровень
db_get_field(RESCONN, 3, var, 32); PlayerInfo[playerid][P_money] = strval(var); // вытащили деньги
format(query,sizeof(query),"Добро пожаловать, %s!\nВведите ваш пароль:",PlayerInfo[playerid][P_name]);
ShowPlayerDialog(playerid, 50, 1, "LOGIN", query, "Вход", "Выход"); // отправили диалог с ИД 50
}
// продолжение паблика OnPlayerConnect
return 1;
}
Диалоги:
PHP код:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == 50) // диалог LOGIN
{
if(!response) // нажал кнопку "Выход"
{ Kick(playerid); return 1; }
else // нажал кнопку "Вход"
{
if(!strlen(inputtext)) // не ввел пароль
{
ShowPlayerDialog(playerid, 50, 1, "LOGIN", "Забыл ввести пароль!\nВводи сюда:", "Вход", "Выход");
return 1;
}
if(!strcmp(inputtext, PlayerInfo[playerid][P_pass], false)) // если верный пароль
{
SendClientMessage(playerid, 0xFFFFFFFF, "Вы успешно вошли");
SetPlayerScore(playerid, PlayerInfo[playerid][P_level]); // поставили уровень
GivePlayerMoney(playerid, PlayerInfo[playerid][P_money]); // дали денег
PlayerInfo[playerid][P_reg] = 1; // вошел на сервер (залогинился)
}
else // если неверный
{
SendClientMessage(playerid, 0xFFFFFFFF, "Вы ввели неверный пароль и были кикнуты с сервера");
Kick(playerid);
}
return 1;
}
}
if(dialogid == 51) // диалог REGISTER
{
if(!response) // нажал кнопку "Выход"
{ Kick(playerid); return 1; }
else // нажал кнопку "далее"
{
if(strlen(inputtext) < 3 || strlen(inputtext) > 16) // слишком короткий или слишком длинный пароль
{
ShowPlayerDialog(playerid, 51, 1, "REGISTER", "Пароль должен быть не длиннее 16 и не короче 3 символов\nВведи свой пароль:", "Далее", "Выход");
return 1;
}
// проверяем пароль на допустимые символы
new allowed = 1;
for (new i=0;i<strlen(inputtext);i++)
{
if (inputtext[i]==0) { allowed = 1; break; } // null
if ((inputtext[i]<48) && (inputtext[i]!=32)) { allowed = 0; break;}
if (inputtext[i]>57 && inputtext[i]<65) { allowed = 0; break;}
if (inputtext[i]>90 && inputtext[i]<97) { allowed = 0; break;}
if (inputtext[i]>122) { allowed = 0; break;}
}
// конец проверки
if(!allowed) // есть недопустимые символы
{
ShowPlayerDialog(playerid, 51, 1, "REGISTER", "Недопустимые символы в пароле, используйте a-z, A-Z, 0-9\nВведи свой пароль:", "Далее", "Выход");
return 1;
}
new query[128]; // переменая для строки запроса
GetPlayerName(playerid, PlayerInfo[playerid][P_name], 32); // получаем имя игрока
format(query,sizeof(query),"INSERT INTO players ( name, pass, level, money ) VALUES ( '%s', '%s', 0, 0)", PlayerInfo[playerid][P_name], inputtext); // добавить новую запись в таблицу
db_query(ServerDB,query); // отправили запрос
PlayerInfo[playerid][P_reg] = 1; // залогинился
SendClientMessage(playerid, 0xFFFFFFFF, "Аккаунт создан!");
PlayerInfo[playerid][P_level] = 0;
PlayerInfo[playerid][P_money] = 0;
return 1;
}
}
// продолжение паблика OnDialogResponse
return 0;
}
6.2 Выдача score, money и прочего...
Так как в пункте 6.1 мы ввели глобальную переменную PlayerInfo, она должна соответствовать действительному значению score, money и прочего.
Поэтому везде, кроме диалога LOGIN рекомендую использовать модифицированные функции:
PHP код:
stock XSetPlayerScore(playerid, score)
{
PlayerInfo[playerid][P_level] = score;
SetPlayerScore(playerid, score);
}
stock XGivePlayerMoney(playerid, money)
{
PlayerInfo[playerid][P_money] += money;
GivePlayerMoney(playerid, money)
}
6.3 Игрок покидает сервер
Когда игрок выходит с сервера, надо сохранять его прогресс.
Паблик OnPlayerDisconnect:
PHP код:
public OnPlayerDisconnect(playerid)
{
if(PlayerInfo[playerid][P_reg] == 1) // если был залогинен
{
new query[128]; // переменая для строки запроса
GetPlayerName(playerid, PlayerInfo[playerid][P_name], 32); // получаем имя игрока
format(query,sizeof(query),"UPDATE players SET level=%d, money=%d WHERE name='%s'", PlayerInfo[playerid][P_level], PlayerInfo[playerid][P_money], PlayerInfo[playerid][P_name]); // обновить данные в таблице
db_query(ServerDB,query); // отправили запрос
}
// продолжение паблика OnPlayerDisconnect
return 1;
}
7. [ВАЖНО] Наиболее частые вопросы [FAQ]
Как удалять строку в таблице?
Для этого используется запрос вида:
DELETE FROM имя_таблицы WHERE условие
Что неправильно в этом запросе?
PHP код:
new query[32];
format(query,sizeof(query),"CREATE TABLE mytable (column1 int, column2 int, column3 int)");
db_query(ServerDB, query);
Дело в том, что для строки запроса используется слишком маленький текстовый массив (32), я советую для всех запросов использовать минимум 512
Можно, ли с помощью SQLite сделать статистику игроков на сайт?
Да, если сайт и сервер находятся на одном хосте - просто нужен будет плагин для php
Как добавить новый столбец в уже созданную таблицу?
Ссылка: >>>
Почему не происходит обновление?
PHP код:
format(query,sizeof(query),"UPDATE players SET pass=%s, tut=%d, level=%d, exp=%d, adminlevel=%d WHERE name='%s'",
PlayerInfo[playerid][pPass],
PlayerInfo[playerid][pTut],
PlayerInfo[playerid][pLevel],
PlayerInfo[playerid][pExp],
PlayerInfo[playerid][pAdminLevel],
PlayerInfo[playerid][pName]);
db_query(MyDB, query);
Потомучто возле %s при форматировании строки запроса ВСЕГДА надо ставить ':
pass='%s'
- - - - -
Вот теперь точно все xD
Задавайте свои вопросы по этой теме, я постараюсь на них ответить!