Пользователь
- Статус
-
Скрыто
- Сообщения
- 84
- Лайки
- 12
1
месяц на сайте
- Тема Автор
- #1
Всем привет!
Предоставляю вашему вниманию простенький вариант системы администрации. Я не исключаю, что гипотетически при наличии новых уникальных идей, мотивации и чутка привитых усилий, данную версию, можно спокойно разогнать в глобальную полноценную систему со всеми зависимости для администраторов сервера.
Аннотации
После подключения к базе данных, добавьте функцию:
В директиве DB_USERS:
Укажите название своей основной таблицы с аккаунтами игроков, если она отличается от стандартной.
Лог обновлений
Версия 0.1:
Добавим ко всем подключаемым библиотекам:
Ко всем константам:
Ко всем глобальным переменным:
Ко всем функциям:
В коллбэк OnGameModeInit:
В коллбэк OnPlayerConnect:
В коллбэк OnPlayerDisconnect:
В коллбэк OnDialogResponse:
В коллбэк OnPlayerCommandReceived:
Ко всем командам:
Предоставляю вашему вниманию простенький вариант системы администрации. Я не исключаю, что гипотетически при наличии новых уникальных идей, мотивации и чутка привитых усилий, данную версию, можно спокойно разогнать в глобальную полноценную систему со всеми зависимости для администраторов сервера.
Аннотации
После подключения к базе данных, добавьте функцию:
Pawn:
admin_SetMySQLConnectionHandle(/* переменная хранящая ID подключения к БД */);
В директиве DB_USERS:
Укажите название своей основной таблицы с аккаунтами игроков, если она отличается от стандартной.
Лог обновлений
Версия 0.1:
Добавим ко всем подключаемым библиотекам:
Pawn:
/*
Для удобства работы, нам понадобится наличие подключения библиотек:
#include <foreach>
#include <Pawn.CMD>
*/
Ко всем константам:
Pawn:
/* Определим директиву с названием основной таблицы администраторов. */
#if !defined DB_USERS_ADMINS
#define DB_USERS_ADMINS "users_admins"
#endif
/* Определим директиву с названием основной таблицы аккаунтов игроков. */
#if !defined DB_USERS
#define DB_USERS "users"
#endif
/* Определим директиву с названием для поля идентификатора аккаунтов игроков. */
#if !defined DB_USERS_ID
#define DB_USERS_ID "id"
#endif
/* Определим директиву хранящую ID подключения к БД. */
#if !defined ADMIN_DB_HANDLE
#define ADMIN_DB_HANDLE GetMySQLHandle()
#endif
/* Определим директивы основных HEX цветов. */
#if !defined HEX_COLOR_ADMIN_CHAT
#define HEX_COLOR_ADMIN_CHAT 0xFF6347FF
#endif
#if !defined HEX_COLOR_ADMIN_SUCCESS
#define HEX_COLOR_ADMIN_SUCCESS 0x46BD38ff
#endif
#if !defined HEX_COLOR_ADMIN_WARNING
#define HEX_COLOR_ADMIN_WARNING 0xAFAFAFFF
#endif
/* Определим директиву, которая устанавливает ID аккаунта игрока. */
#if !defined SetPlayerUserID
#define SetPlayerUserID(%0,%1) g_player_data[%0][PD_ID] = %1
#endif
/* Определим директивы, которые будут получать значения: ID аккаунта в базе и имени. */
#if !defined GetPlayerUserID
#define GetPlayerUserID(%0) g_player_data[%0][PD_ID]
#endif
#if !defined GetPlayerNameEx
#define GetPlayerNameEx(%0) g_player_data[%0][PD_NAME]
#endif
/* Определим директиву с максимальным количеством символов в пароле администратора. */
#if !defined MAX_ADMIN_PASSWORD_LENGTH
#define MAX_ADMIN_PASSWORD_LENGTH 32
#endif
/* Определим директиву с минимальным количеством символов в пароле администратора. */
#if !defined MIN_ADMIN_PASSWORD_LENGTH
#define MIN_ADMIN_PASSWORD_LENGTH 6
#endif
/* Определим директиву с максимальным количеством доступных администраторов в сети. */
#if !defined MAX_ADMINS_COUNT
#define MAX_ADMINS_COUNT (50)
#endif
/* Определим директиву с максимальным уровнем администратора. */
#if !defined MAX_ADMIN_LEVEL
#define MAX_ADMIN_LEVEL (6)
#endif
/* Определим директиву с минимальным уровнем администратора. */
#if !defined MIN_ADMIN_LEVEL
#define MIN_ADMIN_LEVEL (1)
#endif
/* Определим директиву с максимальным размером хэща для пароля администратора. */
#if !defined MAX_ADMIN_PASSWORD_HASH_LENGTH
#define MAX_ADMIN_PASSWORD_HASH_LENGTH (64)
#endif
/* Определим директиву с максимальным размером соли для пароля администратора. */
#if !defined MAX_ADMIN_PASSWORD_SALT_LENGTH
#define MAX_ADMIN_PASSWORD_SALT_LENGTH (12)
#endif
/* Определим директиву с максимальной длиной IP при регистрации администратора. */
#if !defined MAX_ADMIN_REG_IP_LENGTH
#define MAX_ADMIN_REG_IP_LENGTH (16)
#endif
/* Определим директиву c максимальной длиной даты регистрации администратора. */
#if !defined MAX_ADMIN_REG_DATE_LENGTH
#define MAX_ADMIN_REG_DATE_LENGTH (20)
#endif
/* Определим директиву c максимальным количеством попыток для авторизации в панели администратора. */
#if !defined MAX_ADMIN_LOGIN_ATTEMPTS
#define MAX_ADMIN_LOGIN_ATTEMPTS (5)
#endif
Ко всем глобальным переменным:
Pawn:
/* Объявим структуру для удобства работы с ID диалогов. */
enum {
DIALOG_ADMIN_REGISTER = 8999, /* Задайте своё значение свободного диалога. */
DIALOG_ADMIN_LOGIN
}
/* Объявим структуру для удобства работы с доступом к командам администратора, с помощью использования флагов командного процессора Pawn.CMD. */
enum (<<=1) {
ADMIN_COMMAND_LEVEL_6 = 1, /* Доступ к командам 6-го уровня */
ADMIN_COMMAND_LEVEL_5, /* Доступ к командам 5-го уровня */
ADMIN_COMMAND_LEVEL_4, /* Доступ к командам 4-го уровня */
ADMIN_COMMAND_LEVEL_3, /* Доступ к командам 3-го уровня */
ADMIN_COMMAND_LEVEL_2, /* Доступ к командам 2-го уровня */
ADMIN_COMMAND_LEVEL_1 /* Доступ к командам 1-го уровня */
};
/* Объявим структуру с данными администратора. */
enum E_PLAYER_ADMIN_STRUCT {
PA_ID, /* ID аккаунта администратора в базе. */
PA_LEVEL, /* Уровень администратора. */
PA_PASSWORD[MAX_ADMIN_PASSWORD_HASH_LENGTH + 1], /* Хэшированный пароль администратора. */
PA_SALT[MAX_ADMIN_PASSWORD_SALT_LENGTH + 1], /* Соль для хэш пароля администратора. */
PA_REG_IP[MAX_ADMIN_REG_IP_LENGTH], /* IP при регистрации администратора. */
PA_REG_DATE[MAX_ADMIN_REG_DATE_LENGTH + 1], /* Дата при регистрации администратора. */
bool: PA_IS_LOGGED, /* Статус авторизации в панели администратора. */
PA_LOGIN_ATTEMPTS /* Количество попыток для авторизации в панели администратора. */
};
new g_player_admin[MAX_PLAYERS][E_PLAYER_ADMIN_STRUCT];
/* Очистка данных структуры администратора. */
new const NULL_g_player_admin[E_PLAYER_ADMIN_STRUCT] = {
0,
0,
EOS,
EOS,
EOS,
EOS,
false,
MAX_ADMIN_LOGIN_ATTEMPTS
};
/* Объявим структуру с данными аккаунта игрока. */
enum E_PLAYER_DATA_STRUCT {
PD_ID, /* ID аккаунта игрока в базе. */
PD_NAME[MAX_PLAYER_NAME + 1] /* Имя игрока при подключении к серверу. */
};
new g_player_data[MAX_PLAYERS][E_PLAYER_DATA_STRUCT];
/* Очистка данных структуры игрока. */
new const NULL_g_player_data[E_PLAYER_DATA_STRUCT] = {
0,
EOS
};
/* Создадим итератор для хранения авторизованных администраторов. */
new Iterator: AdminPlayers<MAX_ADMINS_COUNT>;
/* Подавить наличие warning 208 */
forward bool: admin_IsPlayerLogged(const playerid);
forward bool: admin_IsPlayerValid(const playerid);
forward bool: admin_IsPasswordLengthValid(const password[]);
Ко всем функциям:
Pawn:
stock admin_GetPlayerAdminID(const playerid)
{
return g_player_admin[playerid][PA_ID];
}
stock admin_SetPlayerAdminID(const playerid, const value)
{
g_player_admin[playerid][PA_ID] = value;
}
stock admin_GetPlayerLevel(const playerid)
{
return g_player_admin[playerid][PA_LEVEL];
}
stock admin_SetPlayerLevel(const playerid, const value)
{
g_player_admin[playerid][PA_LEVEL] = value;
}
stock admin_GetPlayerPassword(const playerid, output_string[], size = sizeof(output_string))
{
strcat((output_string[0] = EOS, output_string), g_player_admin[playerid][PA_PASSWORD], size);
return 1;
}
stock admin_SetPlayerPassword(const playerid, const output_string[], size = sizeof(output_string))
{
strcat(g_player_admin[playerid][PA_PASSWORD], output_string, size);
return 1;
}
stock admin_GetPlayerSalt(const playerid, output_string[], size = sizeof(output_string))
{
strcat((output_string[0] = EOS, output_string), g_player_admin[playerid][PA_SALT], size);
return 1;
}
stock admin_SetPlayerSalt(const playerid, const output_string[], size = sizeof(output_string))
{
strcat(g_player_admin[playerid][PA_SALT], output_string, size);
return 1;
}
stock bool: admin_IsPlayerLogged(const playerid)
{
return (g_player_admin[playerid][PA_IS_LOGGED] != NULL_g_player_admin[PA_IS_LOGGED]);
}
stock admin_GetPlayerLogged(const playerid, const bool: is_logged)
{
return g_player_admin[playerid][PA_IS_LOGGED];
}
stock admin_SetPlayerLogged(const playerid, const bool: is_logged)
{
g_player_admin[playerid][PA_IS_LOGGED] = is_logged;
}
stock admin_GetPlayerLoginAttempts(const playerid, const value)
{
g_player_admin[playerid][PA_LOGIN_ATTEMPTS] = value;
}
stock admin_SetPlayerLoginAttempts(const playerid, const value)
{
g_player_admin[playerid][PA_LOGIN_ATTEMPTS] = value;
}
stock admin_Init()
{
new
Cache: cache_id = mysql_query(ADMIN_DB_HANDLE, !"SHOW TABLES LIKE '"DB_USERS_ADMINS"'", true),
tick = GetTickCount();
if (!cache_num_rows()) {
mysql_query(ADMIN_DB_HANDLE,
"\
CREATE TABLE `"DB_USERS_ADMINS"` ( \
`id` int(11) NOT NULL AUTO_INCREMENT, \
`user_id` int(11) NOT NULL, \
`password` varchar(64) NOT NULL, \
`salt` varchar(12) NOT NULL, \
`level` int(2) NOT NULL, \
`register_IP` varchar(16) NOT NULL, \
`register_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, \
PRIMARY KEY (`id`) \
) ENGINE=InnoDB DEFAULT CHARSET=utf8; \
", false
);
mysql_query(ADMIN_DB_HANDLE,
!"\
CREATE INDEX \
user_id \
ON \
`"DB_USERS_ADMINS"`(user_id) \
", false
);
mysql_query(ADMIN_DB_HANDLE,
!"\
ALTER TABLE \
`"DB_USERS_ADMINS"`\
ADD CONSTRAINT \
`users_admins_users_fk_1` \
FOREIGN KEY \
(`user_id`) \
REFERENCES \
`"DB_USERS"` (`"DB_USERS_ID"`) \
ON DELETE CASCADE ON UPDATE CASCADE \
", false
);
printf("[Debug]: таблица `"DB_USERS_ADMINS"` инициализирована за %d мс.", GetTickCount() - tick);
}
cache_delete(cache_id);
return (!mysql_errno() ? 1 : 0);
}
stock admin_SavePlayerEx(const playerid, const column_name[], const column_value[])
{
static const query[] =
"\
UPDATE "DB_USERS_ADMINS" SET '%e'='%e' WHERE id=%d \
";
new fmt_query[sizeof(query) + (- 2 + 20) + (- 2 + 128) + (- 2 + 11)];
mysql_format(
ADMIN_DB_HANDLE,
fmt_query,
sizeof(fmt_query),
query,
column_name,
column_value,
admin_GetPlayerAdminID(playerid)
);
mysql_tquery(ADMIN_DB_HANDLE, fmt_query, "", !"");
return (!mysql_errno() ? 1 : 0);
}
stock admin_LoadPlayerUserID(playerid)
{
static const query[] =
"\
SELECT u.id FROM users u WHERE u.name='%e' \
";
new fmt_query[sizeof(query) + (- 2 + MAX_PLAYER_NAME)];
format(
fmt_query,
sizeof fmt_query,
query,
GetPlayerNameEx(playerid)
);
mysql_tquery(ADMIN_DB_HANDLE, fmt_query, !"@__OnPlayerLoadUserID", !"d", playerid);
return (!mysql_errno() ? 1 : 0);
}
stock admin_LoadPlayerData(const playerid)
{
static const query[] =
"\
SELECT * FROM users u \
LEFT JOIN "DB_USERS_ADMINS" a ON u.id=a.user_id \
WHERE u.id=%d \
";
new fmt_query[sizeof(query) + (- 2 + 11)];
format(
fmt_query,
sizeof fmt_query,
query,
GetPlayerUserID(playerid)
);
mysql_tquery(ADMIN_DB_HANDLE, fmt_query, !"@__OnPlayerLoadAdminData", !"d", playerid);
return (!mysql_errno() ? 1 : 0);
}
stock admin_PlayerCreate(const playerid)
{
static const query[] =
"\
INSERT INTO "DB_USERS_ADMINS" (level, register_IP) VALUES (%d, '%e') \
";
new
fmt_query[sizeof(query) + (- 2 + MAX_ADMIN_REG_IP_LENGTH)],
tmp_ip[MAX_ADMIN_REG_IP_LENGTH];
GetPlayerIp(playerid, tmp_ip, MAX_ADMIN_REG_IP_LENGTH);
admin_SetPlayerLevel(playerid, MIN_ADMIN_LEVEL);
g_player_admin[playerid][PA_PASSWORD][0] = NULL_g_player_admin[PA_PASSWORD];
g_player_admin[playerid][PA_SALT][0] = NULL_g_player_admin[PA_SALT];
mysql_format(
ADMIN_DB_HANDLE,
fmt_query,
sizeof(fmt_query),
query,
tmp_ip,
MIN_ADMIN_LEVEL
);
mysql_tquery(ADMIN_DB_HANDLE, fmt_query, !"@__OnPlayerLoadAdminID", !"d", playerid);
Iter_Add(AdminPlayers, playerid);
SendClientMessage(playerid, HEX_COLOR_ADMIN_SUCCESS, !"Для регистрации пароля администратора, используйте команду - /aduty.");
return (!mysql_errno() ? 1 : 0);
}
stock admin_PlayerUpdate(const playerid)
{
static const query[] =
"\
UPDATE "DB_USERS_ADMINS" SET level=%d WHERE id=%d \
";
new fmt_query[sizeof(query) + (- 2 + 2) + (- 2 + 11)];
mysql_format(
ADMIN_DB_HANDLE,
fmt_query,
sizeof(fmt_query),
query,
admin_GetPlayerLevel(playerid),
admin_GetPlayerAdminID(playerid)
);
mysql_tquery(ADMIN_DB_HANDLE, fmt_query, "", !"");
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Ваш уровень администратора был повышен.");
return (!mysql_errno() ? 1 : 0);
}
stock admin_PlayerRemove(const playerid)
{
static const query[] =
"\
DELETE FROM "DB_USERS_ADMINS" WHERE id=%d \
";
new fmt_query[sizeof(query) + (- 2 + 11)];
mysql_format(
ADMIN_DB_HANDLE,
fmt_query,
sizeof(fmt_query),
query,
admin_GetPlayerAdminID(playerid)
);
mysql_tquery(ADMIN_DB_HANDLE, fmt_query, "", !"");
if (Iter_Contains(AdminPlayers, playerid)) {
Iter_Remove(AdminPlayers, playerid);
}
admin_SetPlayerLogged(playerid, false);
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы были сняты с должности администратора.");
return 1;
}
stock admin_ClearPlayerData(const playerid)
{
g_player_data[playerid] = NULL_g_player_data;
}
stock admin_ClearPlayerAdminData(const playerid)
{
if (admin_IsPlayerLogged(playerid)) {
g_player_admin[playerid] = NULL_g_player_admin;
if (Iter_Contains(AdminPlayers, playerid)) {
Iter_Remove(AdminPlayers, playerid);
}
}
return 1;
}
stock bool: admin_IsPlayerValid(const playerid)
{
return (g_player_admin[playerid][PA_LEVEL] != NULL_g_player_admin[PA_LEVEL]);
}
stock bool: admin_IsPasswordLengthValid(const password[])
{
if (!(MIN_ADMIN_PASSWORD_LENGTH <= strlen(password) <= MAX_ADMIN_PASSWORD_LENGTH)) {
return false;
}
return true;
}
stock admin_GeneratePlayerPassword(const playerid, password[])
{
GenerateRandomString(
g_player_admin[playerid][PA_SALT],
MAX_ADMIN_PASSWORD_SALT_LENGTH,
MAX_ADMIN_PASSWORD_SALT_LENGTH + 1
);
SHA256_PassHash(
password,
g_player_admin[playerid][PA_SALT],
g_player_admin[playerid][PA_PASSWORD],
MAX_ADMIN_PASSWORD_HASH_LENGTH
);
return 1;
}
stock admin_SendMessage(const color, const message[])
{
foreach (new idx : AdminPlayers) {
SendClientMessage(idx, color, message);
}
return 1;
}
stock ShowPlayerAdminRegisterDialog(playerid)
{
return ShowPlayerDialog(
playerid,
DIALOG_ADMIN_REGISTER,
DIALOG_STYLE_INPUT,
!"{FFFFFF}Регистрация пароля администратора",
!"{FFFFFF}Придумайте ваш личный пароль от панели администратора и введите его в диалоговое поле ниже:\n\
– Важно:\n\
• {AFAFAF}Пароль администратора должен быть не менее "#MIN_ADMIN_PASSWORD_LENGTH" и не более "#MAX_ADMIN_PASSWORD_LENGTH" символов в длину.\n\
• {AFAFAF}Пароль администратора может состоять только из латинских символов и цифр (aA-zZ, 0-9).\n\
Пример надёжного пароля администратора: 32asbe501Tg67F9k",
!"Далее", !"Закрыть"
);
}
stock ShowPlayerAdminLoginDialog(playerid)
{
return ShowPlayerDialog(
playerid,
DIALOG_ADMIN_LOGIN,
DIALOG_STYLE_PASSWORD,
!"{FFFFFF}Авторизация администратора",
!"{FFFFFF}Введите ваш личный пароль администратора в диалоговое поле ниже:",
!"Далее", !"Закрыть"
);
}
/*
auxiliary functions
*/
static stock GenerateRandomString(
result_str[],
length,
const size = sizeof(result_str),
const alphabet[] = DEFAULT_ALPHABET,
const alphabet_size = sizeof(alphabet)) // by ziggi
{
result_str[0] = '\0';
if (length >= size) {
length = size - 1;
}
if (length < 1) {
return 0;
}
for (new i = 0; i < length; i++) {
result_str[i] = alphabet[ random(alphabet_size - 1) ];
}
return 1;
}
static stock bool: IsValidPasswordChars(const string[])
{
for (new i = 0; string[i] != '\0'; ++i) {
switch (string[i]) {
case 'a'..'z', 'A'..'Z', '0'..'9': {
continue;
}
default: {
return false;
}
}
}
return true;
}
static stock bool: strequal(const string1[], const string2[], bool:ignorecase = false, length = cellmax) // by m1n1vv.
{
new
s1 = string1[0],
s2 = string2[0];
if ((s1 == '\0' || s2 == '\0') && (s1 != s2))
return false;
return strcmp(string1, string2, ignorecase, length) == 0;
}
@__OnPlayerLoadUserID(playerid);
@__OnPlayerLoadUserID(playerid)
{
new row_count = cache_num_rows();
if (row_count) {
new user_id;
cache_get_value_name_int(0, !"id", user_id);
SetPlayerUserID(playerid, user_id);
admin_LoadPlayerData(playerid);
}
return 1;
}
@__OnPlayerLoadAdminData(playerid);
@__OnPlayerLoadAdminData(playerid)
{
new row_count = cache_num_rows();
if (row_count) {
cache_get_value_name_int(0, !"id", g_player_admin[playerid][PA_ID]);
cache_get_value_name_int(0, !"level", g_player_admin[playerid][PA_LEVEL]);
cache_get_value_name(0, !"password", g_player_admin[playerid][PA_PASSWORD], MAX_ADMIN_PASSWORD_HASH_LENGTH);
cache_get_value_name(0, !"salt", g_player_admin[playerid][PA_SALT], MAX_ADMIN_PASSWORD_SALT_LENGTH);
cache_get_value_name(0, !"register_IP", g_player_admin[playerid][PA_REG_IP], MAX_ADMIN_REG_IP_LENGTH);
cache_get_value_name(0, !"register_date", g_player_admin[playerid][PA_REG_DATE], MAX_ADMIN_REG_DATE_LENGTH);
new buffer[MAX_ADMIN_PASSWORD_HASH_LENGTH];
admin_GetPlayerPassword(playerid, buffer);
if (isnull(buffer)) {
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы вошли как незарегистрированный администратор.");
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Для регистрации пароля используйте - /aduty.");
} else {
static const message[] = "Вы вошли как администратор (%d) уровня. Для авторизации используйте - /aduty.";
new fmt_message[sizeof(message) + (- 2 + 2)];
format(
fmt_message,
sizeof(fmt_message),
message,
g_player_admin[playerid][PA_LEVEL]
);
SendClientMessage(playerid, HEX_COLOR_ADMIN_SUCCESS, fmt_message);
}
Iter_Add(AdminPlayers, playerid);
}
return 1;
}
@__OnPlayerLoadAdminID(playerid);
@__OnPlayerLoadAdminID(playerid)
{
admin_SetPlayerAdminID(playerid, cache_insert_id());
return 1;
}
В коллбэк OnGameModeInit:
Pawn:
public OnGameModeInit()
{
admin_Init();
return 1;
}
В коллбэк OnPlayerConnect:
Pawn:
public OnPlayerConnect(playerid)
{
admin_ClearPlayerData(playerid);
GetPlayerName(playerid, g_player_data[playerid][PD_NAME], MAX_PLAYER_NAME);
admin_LoadPlayerUserID(playerid);
return 1;
}
В коллбэк OnPlayerDisconnect:
Pawn:
public OnPlayerDisconnect(playerid, reason)
{
admin_ClearPlayerAdminData(playerid);
return 1;
}
В коллбэк OnDialogResponse:
Pawn:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch (dialogid) {
case DIALOG_ADMIN_REGISTER: {
if (!response) {
return 0;
}
if (!admin_IsPasswordLengthValid(inputtext)) {
SendClientMessage(
playerid,
HEX_COLOR_ADMIN_WARNING,
!"Пароль должен быть не менее \
"#MIN_ADMIN_PASSWORD_LENGTH" и не более \
"#MAX_ADMIN_PASSWORD_LENGTH" символов в длину."
);
return ShowPlayerAdminRegisterDialog(playerid);
}
if (!IsValidPasswordChars(inputtext)) {
SendClientMessage(
playerid,
HEX_COLOR_ADMIN_WARNING,
!"Пароль может состоять только из латинских символов и цифр (aA-zZ, 0-9)"
);
return ShowPlayerAdminRegisterDialog(playerid);
}
admin_GeneratePlayerPassword(playerid, inputtext);
admin_SavePlayerEx(playerid, "password", g_player_admin[playerid][PA_PASSWORD]);
admin_SavePlayerEx(playerid, "salt", g_player_admin[playerid][PA_SALT]);
admin_SetPlayerLogged(playerid, true);
Iter_Add(AdminPlayers, playerid);
SendClientMessage(playerid, HEX_COLOR_ADMIN_SUCCESS, !"Ваш пароль от панели администратора: ");
SendClientMessage(playerid, -1, inputtext);
return 1;
}
case DIALOG_ADMIN_LOGIN: {
if (!response) {
return 0;
}
if (!admin_IsPasswordLengthValid(inputtext)) {
SendClientMessage(
playerid,
HEX_COLOR_ADMIN_WARNING,
!"Пароль должен быть не менее \
"#MIN_ADMIN_PASSWORD_LENGTH" и не более \
"#MAX_ADMIN_PASSWORD_LENGTH" символов в длину."
);
return ShowPlayerAdminLoginDialog(playerid);
}
new hash[MAX_ADMIN_PASSWORD_HASH_LENGTH + 1];
SHA256_PassHash(
inputtext,
g_player_admin[playerid][PA_SALT],
hash,
MAX_ADMIN_PASSWORD_HASH_LENGTH
);
if (strequal(hash, g_player_admin[playerid][PA_PASSWORD])) {
admin_SetPlayerLogged(playerid, true);
if (!Iter_Contains(AdminPlayers, playerid)) {
Iter_Add(AdminPlayers, playerid);
}
SendClientMessage(playerid, HEX_COLOR_ADMIN_SUCCESS, !"Вы успешно авторизовались в панели администратора.");
} else {
if (--g_player_admin[playerid][PA_LOGIN_ATTEMPTS] <= 0) {
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы исчерпали все попытки ввода пароля администратора и были кикнуты.");
return Kick(playerid);
}
ShowPlayerAdminLoginDialog(playerid);
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Пароли не совпадают. Повторите попытку.");
}
return 1;
}
}
return 1;
}
В коллбэк OnPlayerCommandReceived:
Pawn:
public OnPlayerCommandReceived(playerid, cmd[], params[], flags)
{
if (((flags & ADMIN_COMMAND_LEVEL_1) ||
(flags & ADMIN_COMMAND_LEVEL_2) ||
(flags & ADMIN_COMMAND_LEVEL_3) ||
(flags & ADMIN_COMMAND_LEVEL_4) ||
(flags & ADMIN_COMMAND_LEVEL_5) ||
(flags & ADMIN_COMMAND_LEVEL_6))
&& !admin_IsPlayerLogged(playerid) && admin_IsPlayerValid(playerid)) {
SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы не авторизированы в панели администратора.");
return 0;
}
if ((flags & ADMIN_COMMAND_LEVEL_1) && admin_GetPlayerLevel(playerid) < 1 ||
(flags & ADMIN_COMMAND_LEVEL_2) && admin_GetPlayerLevel(playerid) < 2 ||
(flags & ADMIN_COMMAND_LEVEL_3) && admin_GetPlayerLevel(playerid) < 3 ||
(flags & ADMIN_COMMAND_LEVEL_4) && admin_GetPlayerLevel(playerid) < 4 ||
(flags & ADMIN_COMMAND_LEVEL_5) && admin_GetPlayerLevel(playerid) < 5 ||
(flags & ADMIN_COMMAND_LEVEL_6) && admin_GetPlayerLevel(playerid) < 6) {
return 0;
}
return 1;
}
Ко всем командам:
Pawn:
flags:aduty(ADMIN_COMMAND_LEVEL_1)
cmd:aduty(playerid)
{
if (Iter_Count(AdminPlayers) > MAX_ADMINS_COUNT) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Превышен лимит администраторов на сервере.");
}
if (admin_IsPlayerLogged(playerid)) {
admin_SetPlayerLogged(playerid, false);
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы вышли из панели администратора.");
}
new buffer[MAX_ADMIN_PASSWORD_HASH_LENGTH];
admin_GetPlayerPassword(playerid, buffer);
if (isnull(buffer)) {
ShowPlayerAdminRegisterDialog(playerid);
} else {
ShowPlayerAdminLoginDialog(playerid);
}
return 1;
}
flags:create_admin(ADMIN_COMMAND_LEVEL_6)
cmd:create_admin(playerid, params[])
{
new targetid = INVALID_PLAYER_ID;
if (sscanf(params, !"u", targetid)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, "/create_admin: [ID / Часть имени]");
}
if (targetid == INVALID_PLAYER_ID) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанного игрока нет на сервере.");
}
if (targetid == playerid) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы указали свой ID.");
}
if (admin_IsPlayerValid(targetid)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанный игрок уже администратор.");
}
if (Iter_Count(AdminPlayers) > MAX_ADMINS_COUNT) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Превышен лимит администраторов на сервере.");
}
admin_PlayerCreate(targetid);
return 1;
}
flags:edit_admin(ADMIN_COMMAND_LEVEL_6)
cmd:edit_admin(playerid, params[])
{
new
targetid = INVALID_PLAYER_ID,
level;
if (sscanf(params, !"ud", targetid, level)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, "/edit_admin: [ID / Часть имени] [Уровень]");
}
if (targetid == INVALID_PLAYER_ID) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанного игрока нет на сервере.");
}
if (targetid == playerid) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы указали свой ID.");
}
if (!admin_IsPlayerValid(targetid)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанный игрок не администратор.");
}
if (!(0 <= level <= MAX_ADMIN_LEVEL)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Некорректный уровень администратора.");
}
if (admin_GetPlayerLevel(targetid) == level) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанный администратор такого же уровня.");
}
admin_SetPlayerLevel(playerid, level);
admin_PlayerUpdate(targetid);
return 1;
}
flags:remove_admin(ADMIN_COMMAND_LEVEL_6)
cmd:remove_admin(playerid, params[])
{
new targetid = INVALID_PLAYER_ID;
if (sscanf(params, !"u", targetid)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, "/remove_admin: [ID / Часть имени]");
}
if (targetid == INVALID_PLAYER_ID) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанного игрока нет на сервере.");
}
if (targetid == playerid) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Вы указали свой ID.");
}
if (!admin_IsPlayerValid(targetid)) {
return SendClientMessage(playerid, HEX_COLOR_ADMIN_WARNING, !"Указанный игрок не администратор.");
}
admin_PlayerRemove(targetid);
return 1;
}
1. Вся система полностью переведена в инклуд для подключения к вашему игровому моду.
2. Убрано использование флагов.
3. Добавлена функция admin_GetAccessCommand(const playerid, const level)
4. Исправлен баг при загрузке данных администратора.
5. Исправлен баг при авторизации в панели администратора.
6. Добавлена функция admin_IsPlayerPasswordEqual(password[], expected_hash[], salt[])
7. Добавлена функция admin_GeneratePlayerPassword(const playerid, password[])
8. Добавлена функция admin_SetMySQLConnectionHandle(MySQL: handle)
9. Добавлена функция admin_GetPlayerOnlineByID(const player_name[])
10. Добавлена команда /admin - отправить сообщение в чат администрации.
11. Добавлена команда /admins - посмотреть список администрации онлайн.
12. Добавлена команда /off_admins - посмотреть список администрации (OFFLINE).
13. Добавлена команда /ahelp - посмотреть список доступных команд администора 1-6 уровня.
14. Добавлена команда /off_create_admin - создать нового администратора (OFFLINE).
15. Добавлена команда /off_edit_admin - изменить уровень администратора (OFFLINE).
16. Добавлена команда /off_remove_admin - снять администратора (OFFLINE).
2. Убрано использование флагов.
3. Добавлена функция admin_GetAccessCommand(const playerid, const level)
4. Исправлен баг при загрузке данных администратора.
5. Исправлен баг при авторизации в панели администратора.
6. Добавлена функция admin_IsPlayerPasswordEqual(password[], expected_hash[], salt[])
7. Добавлена функция admin_GeneratePlayerPassword(const playerid, password[])
8. Добавлена функция admin_SetMySQLConnectionHandle(MySQL: handle)
9. Добавлена функция admin_GetPlayerOnlineByID(const player_name[])
10. Добавлена команда /admin - отправить сообщение в чат администрации.
11. Добавлена команда /admins - посмотреть список администрации онлайн.
12. Добавлена команда /off_admins - посмотреть список администрации (OFFLINE).
13. Добавлена команда /ahelp - посмотреть список доступных команд администора 1-6 уровня.
14. Добавлена команда /off_create_admin - создать нового администратора (OFFLINE).
15. Добавлена команда /off_edit_admin - изменить уровень администратора (OFFLINE).
16. Добавлена команда /off_remove_admin - снять администратора (OFFLINE).
1. Исправлена MySQL ошибка при добавлении нового администратора (OFFLINE).
2. В функции admin_GetAccessCommand(const playerid, const level), убрано использование тернарного оператора.
3. Убрана функция admin_GetPlayerLogged(const playerid, const bool: is_logged).
4. Убрана функция admin_SetPlayerLogged(const playerid, const bool: is_logged).
5. Изменена функция admin_IsPlayerLogin(const playerid). Теперь для проверки на авторизацию в панели администратора используется функция Iter_Contains.
6. В команде /admins, исправлена ошибка отображения диалога при отсутствии активных администраторов.
7. Обновлены/добавлены директивы HEX_COLOR_ADMIN_DEFAULT, HEX_COLOR_ADMIN_CHAT, HEX_COLOR_ADMIN_SUCCESS, HEX_COLOR_ADMIN_ERROR, HEX_COLOR_ADMIN_NOTE, для удобства редактирования цветовой гаммы.
8. Исправлена ошибка, при которой была возможность использовать команды без необходимости авторизации в панели администратора.
9. Исправлена ошибка при компиляции с автоматическим подсчётом размера массива.
10. Исправлена ошибка при компиляции при использовании static enum.
11. Исправлена ошибка при компиляции с перехватом public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]).
13. Убрана директива MAX_ADMIN_REG_IP_LENGTH. Теперь IP-адрес храниться как число.
14. Убраны директивы хранения ID диалогов. Добавлено перечисление с ID диалогов.
15. Добавлена команда /give_weapon для администратора 4-го уровня — выдать оружие игроку.
16. Добавлена команда /slap для администратора 4-го уровня — подкинуть игрока.
18. Добавлена команда /goto для администратора 2-го уровня — ТП к игроку.
19. Добавлена команда /gethere для администратора 3-го уровня — ТП игрока к себе.
20. Добавлена команда /setworld для администратора 4-го уровня — изменить виртуальный мир игроку.
21. Добавлена команда /setint для администратора 4-го уровня — изменить интерьер игроку.
22. Добавлена команда /settime для администратора 5-го уровня — изменить время на сервере.
23. Добавлена команда /setweather для администратора 5-го уровня — изменить погоду на сервере.
24. Добавлена команда /asay для администратора 2-го уровня — написать в общий чат.
25. Добавлена команда /answer для администратора 1-го уровня — ответить игроку.
26. Добавлена команда /gotopos для администратора 3-го уровня — ТП по координатам.
27. Добавлена команда /cc для администратора 3-го уровня — очистить чат.
28. Добавлена команда /eject для администратора 1-го уровня — выкинуть игрока из транспортного средства.
29. Добавлена команда /freeze для администратора 2-го уровня — заморозка игрока.
30. Добавлена команда /unfreeze для администратора 2-го уровня — разморозка игрока.
31. Добавлена команда /weapon для администратора 4-го уровня — информация об оружии игрока.
32. Добавлена команда /spawnveh для администратора 2-го уровня — телепортировать транспорта на спавн.
33. Добавлена команда /repairveh для администратора 4-го уровня — починка транспорта.
34. Добавлена команда /veh для администратора 6-го уровня — создать транспорт.
35. Добавлена команда /setskin для администратора 4-го уровня — изменить скин игроку.
36. Добавлена команда /showstats для администратора 1-го уровня — показать статистику игрока.
37. Добавлена команда /set_health для администратора 4-го уровня — установить жизни игроку.
38. Добавлена команда /set_armour для администратора 4-го уровня — установить броню игроку.
39. Добавлена команда /set_money для администратора 4-го уровня — установить деньги игроку.
40. Добавлена команда /aspawn для администратора 3-го го уровня — заспавить игрока.
41. Добавлена команда /dveh для администратора 6-го уровня — удалить транспорт.
42. Добавлена команда /set_prefix для администратора 6-го уровня — установить префикс администратору.
43. Добавлена команда /prefix_color для администратора 6-го уровня — установить цвет префикса администратору.
2. В функции admin_GetAccessCommand(const playerid, const level), убрано использование тернарного оператора.
3. Убрана функция admin_GetPlayerLogged(const playerid, const bool: is_logged).
4. Убрана функция admin_SetPlayerLogged(const playerid, const bool: is_logged).
5. Изменена функция admin_IsPlayerLogin(const playerid). Теперь для проверки на авторизацию в панели администратора используется функция Iter_Contains.
6. В команде /admins, исправлена ошибка отображения диалога при отсутствии активных администраторов.
7. Обновлены/добавлены директивы HEX_COLOR_ADMIN_DEFAULT, HEX_COLOR_ADMIN_CHAT, HEX_COLOR_ADMIN_SUCCESS, HEX_COLOR_ADMIN_ERROR, HEX_COLOR_ADMIN_NOTE, для удобства редактирования цветовой гаммы.
8. Исправлена ошибка, при которой была возможность использовать команды без необходимости авторизации в панели администратора.
9. Исправлена ошибка при компиляции с автоматическим подсчётом размера массива.
10. Исправлена ошибка при компиляции при использовании static enum.
11. Исправлена ошибка при компиляции с перехватом public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]).
13. Убрана директива MAX_ADMIN_REG_IP_LENGTH. Теперь IP-адрес храниться как число.
14. Убраны директивы хранения ID диалогов. Добавлено перечисление с ID диалогов.
15. Добавлена команда /give_weapon для администратора 4-го уровня — выдать оружие игроку.
16. Добавлена команда /slap для администратора 4-го уровня — подкинуть игрока.
18. Добавлена команда /goto для администратора 2-го уровня — ТП к игроку.
19. Добавлена команда /gethere для администратора 3-го уровня — ТП игрока к себе.
20. Добавлена команда /setworld для администратора 4-го уровня — изменить виртуальный мир игроку.
21. Добавлена команда /setint для администратора 4-го уровня — изменить интерьер игроку.
22. Добавлена команда /settime для администратора 5-го уровня — изменить время на сервере.
23. Добавлена команда /setweather для администратора 5-го уровня — изменить погоду на сервере.
24. Добавлена команда /asay для администратора 2-го уровня — написать в общий чат.
25. Добавлена команда /answer для администратора 1-го уровня — ответить игроку.
26. Добавлена команда /gotopos для администратора 3-го уровня — ТП по координатам.
27. Добавлена команда /cc для администратора 3-го уровня — очистить чат.
28. Добавлена команда /eject для администратора 1-го уровня — выкинуть игрока из транспортного средства.
29. Добавлена команда /freeze для администратора 2-го уровня — заморозка игрока.
30. Добавлена команда /unfreeze для администратора 2-го уровня — разморозка игрока.
31. Добавлена команда /weapon для администратора 4-го уровня — информация об оружии игрока.
32. Добавлена команда /spawnveh для администратора 2-го уровня — телепортировать транспорта на спавн.
33. Добавлена команда /repairveh для администратора 4-го уровня — починка транспорта.
34. Добавлена команда /veh для администратора 6-го уровня — создать транспорт.
35. Добавлена команда /setskin для администратора 4-го уровня — изменить скин игроку.
36. Добавлена команда /showstats для администратора 1-го уровня — показать статистику игрока.
37. Добавлена команда /set_health для администратора 4-го уровня — установить жизни игроку.
38. Добавлена команда /set_armour для администратора 4-го уровня — установить броню игроку.
39. Добавлена команда /set_money для администратора 4-го уровня — установить деньги игроку.
40. Добавлена команда /aspawn для администратора 3-го го уровня — заспавить игрока.
41. Добавлена команда /dveh для администратора 6-го уровня — удалить транспорт.
42. Добавлена команда /set_prefix для администратора 6-го уровня — установить префикс администратору.
43. Добавлена команда /prefix_color для администратора 6-го уровня — установить цвет префикса администратору.