Question

здравствуйте, подскажите как сделать так, чтобы команда /makeadmin после назначения игрока на админа, или повышение админа, добавляла в базу данных админку игроку, чтобы в таблице users меняла уровень админки, а в таблице admins добавляла игрока и также изменяла уровень.

Code:

CMD:makeadmin(playerid, params[])
{
    new string[128];
    if(GetAdmin(playerid, adminLogin) == falsereturn SCM(playerid, 0xA3A3A3FF"{C20000}[Ошибка]"C_GREY" Вы не являетесь администратором");
    if(GetAdmin(playerid, adminLevel) < 6return SCM(playerid, 0xA3A3A3FF"{C20000}[Ошибка]"C_GREY" Вы не можете использовать данную команду.");
    if(sscanf(params, "ii", params[0], params[1])) return SCM(playerid, 0xA3A3A3AA"{C20000}[Ошибка]"C_GREY" Введите: /makeadmin [ID] [Level].");
    if(!IsPlayerConnected(params[0])) return SCM(playerid, 0xA3A3A3FF"{C20000}[Ошибка]"C_GREY" Данный игрок не в сети!");
    if(params[1] < 0 || params[1] > 8return SCM(playerid, 0xA3A3A3FF"{C20000}[Ошибка]"C_GREY" Уровень администратора [0-8]");
    InfoPlayer[params[0]][pAdmin] = params[1];
    format(string, sizeof(string), "Администратор %s изменил ваш уровень администратора на: %d", InfoPlayer[playerid][pName], params[1]);
    SCM(params[0], 0xFFFFFFAA, string);
    return true;
}

Screens - click

 

Снимок экрана 2024-07-25 234801.png

Снимок экрана 2024-07-25 234904.png

Снимок экрана 2024-07-25 234923.png

Снимок экрана 2024-07-25 235212.png

Share this post


Link to post

11 answers to this question

  • 0

@Surfer_Selectrum, это называется избыточность: вы в двух таблицах храните и уровень прав администратора, и имя пользователя. В вашем случае правильнее хранить в столбце admin таблицы users идентификатор дескриптора (описателя) прав администратора в таблице admins. Тогда таблица admins не будет содержать столбец name, а таблица users в столбце admin не будет хранить уровень прав администратора текущего пользователя.

 

Тем не менее, дабы все-таки ответить на ваш вопрос, сообщаю, что в приведенном вами фрагменте кода отсутствуют какие-либо функции для записи данных в базу данных. Возможно, InfoPlayer какой-то навороченный макрос, а может быть сохранение текущих данных в базу данных осуществляется по флагу от какого-нибудь таймера, либо по событию.

Share this post


Link to post
  • 0

Если я правильно понял, то:
 

Создать в таблицу admins:

mysql_format(mysql, query, sizeof query, "INSERT INTO admins (name, password, level) VALUES (%s, %d, '%d')", name, password, level);

    mysql_query(mysql, query, false);


Изменить в Users:

mysql_format(mysql, query, sizeof query, "UPDATE users SET admin=%d", admin);
    mysql_query(mysql, query, false);

только все замени под себя

Если я все же правильно тебя понял, то нужно сделать проверку на то, есть ли уже в admins строка

Edited by moffes

Share this post


Link to post
  • 0


@moffes, не совсем. Идея в том, чтобы можно было сопоставить данные из таблиц users и admins на основе общего поля (идентификатора аккаунта) через операторы соединения (JOIN).

 

Таблица users должна иметь следующие столбцы:

  1. id (уникальный идентификатор аккаунта).
  2. name.
  3. password.
  4. sex.
  5. skin.
  6. money.
  7. regip.
  8. lastip.

Обратите внимание на отсутствие столбца admin!

 

Таблица admins должна иметь следующие столбцы:

  1. id (уникальный номер записи).
  2. accountid (уникальный идентификатор аккаунта, аналогичный полю id таблицы users.
  3. password.
  4. level.

 

Теперь для выдачи прав администратора игроку нужно создать новую запись в таблице admins. Для изменения текущих прав администратора нужно, соответственно, изменить существующую запись. Удаление записи влечет лишение игрока прав администратора. Для того, чтобы при подключении игрока к серверу одним запросом получить всю информацию как из таблицы users, так и из таблицы admins, нужно соединить обе этих таблицы по столбцу admins. Например, вот так:

"SELECT * FROM users LEFT JOIN admins ON users.id = admins.accountid WHERE users.name = '%s' and users.password = '%s'", PlayerInfo[playerid][pAccountID], PlayerInfo[playerid][pPassword]

Пример выше очень примитивен и не учитывает тот факт, что, скажем, хранение паролей в базе данных "как есть" мягко говоря плохое решение.

Share this post


Link to post
  • 0

@Cawfee а куда этот код в конце вставлять примерно?

Share this post


Link to post
  • 0

@Surfer_Selectrum Чтобы решить твою проблему правильно: нужно учитывать несколько моментов архитектуры базы данных и обеспечения целостности данных. В твоем же случае наблюдается что ты хранишь уровень администратора и имя пользователя в двух таблицах (`admins` и `users`), что не является оптимальным подходом.

 

Правильнее было бы использовать одну таблицу для хранения информации об уровне администратора и ссылаться на нее из основной таблицы пользователей. Это уменьшит избыточность и упростит управление данными. Например, в таблице `users` у тебя должен быть столбец `admin_id`, который ссылается на идентификатор в таблице `admins`.

 

Твой текущий код не включает операции вставки и обновления в базу данных. Вот как это можно сделать, сохраняя корректность и эффективность работы:

CMD:makeadmin(playerid, params[])
{
    new string[128];
    new pname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pname, sizeof(pname));

    if(GetAdmin(playerid, adminLogin) == falsereturn SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Вы не являетесь администратором");
    if(GetAdmin(playerid, adminLevel) < 6return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Вы не можете использовать данную команду");

    if(!IsPlayerConnected(params[1])) return SCM(playerid, 0xA3A3A3AA"[C20000]Ошибка[]C_GREY] Данный игрок не в сети!");
    if(!strlen(params[1]) || !strlen(params[2])) return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Введите: /makeadmin [ID игрока] [Уровень администратора 0-8]");

    new targetid = strval(params[1]);
    new level = strval(params[2]);

    if(level < 0 || level > 8return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Уровень администратора [0-8]!");

    format(string, sizeof(string), "SELECT `id` FROM `users` WHERE `name`='%s'", pname);
    new Cache:cache = db_query(mysqlHandle, string);
    if(cache_get_row_count(cache) == 0) {
        db_free_result(cache);
        return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Пользователь не найден в базе данных");
    }
    db_free_result(cache);

    if(level == 0) {
        format(string, sizeof(string), "DELETE FROM `admins` WHERE `name`='%s'", pname);
        db_query(mysqlHandle, string);
    } else {
        format(string, sizeof(string), "REPLACE INTO `admins` (`name`, `password`, `level`) VALUES ('%s', '%s', %d)", pname, "somepassword", level);
        db_query(mysqlHandle, string);
    }

    format(string, sizeof(string), "UPDATE `users` SET `admin`=%d WHERE `name`='%s'", level, pname);
    db_query(mysqlHandle, string);

    InfoPlayer[targetid][pName] = level;
    format(string, sizeof(string), "Администратор %s изменил ваш уровень администратора на: %d", pname, level);
    SCM(params[0], 0xFFFFFFAA, string);

    return true;
}

 

В этом коде выполняется сначала проверка наличия пользователя в таблице `users`. Если он найден, затем проверяется уровень администратора. Если он равен 0, то запись удаляется из таблицы `admins`. В противном случае используется `REPLACE INTO`, чтобы обновить или вставить новую запись в `admins`. Также обновляется поле `admin` в таблице `users`.

Такой подход минимизирует избыточность данных и поддерживает целостность и консистентность базы данных.

Edited by D2DChat
Причина: Орфографические ошибки.

Share this post


Link to post
  • 0

@D2DChat спасибо! сейчас пойду проверять.

Share this post


Link to post
  • 0

TS Posted (edited) · Report post

@D2DChat 

Снимок экрана 2024-07-27 223136.png

@D2DChat ../server/admins/cmd.inc(30) : error 017: undefined symbol "mysqlHandle"
../server/admins/cmd.inc(30) : warning 213: tag mismatch: expected tag "Cache", but found "DBResult"
../server/admins/cmd.inc(31) : warning 213: tag mismatch: expected tag none ("_"), but found "Cache"
../server/admins/cmd.inc(32) : warning 213: tag mismatch: expected tag "DBResult", but found "Cache"
../server/admins/cmd.inc(35) : warning 213: tag mismatch: expected tag "DBResult", but found "Cache"
../server/admins/cmd.inc(39) : error 017: undefined symbol "mysqlHandle"
../server/admins/cmd.inc(42) : error 017: undefined symbol "mysqlHandle"
../server/admins/cmd.inc(46) : error 017: undefined symbol "mysqlHandle"

некоторые ошибки исправил

 

Edited by Surfer_Selectrum

Share this post


Link to post
  • 0

@Surfer_Selectrum Могу узнать какая у вас версия библиотеки MYSQL ?

Share this post


Link to post
  • 0

@D2DChat 5.6

Share this post


Link to post
  • 0

@Surfer_Selectrum 

CMD:makeadmin(playerid, params[])
{
    new string[256];
    new pname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pname, sizeof(pname));

    if(GetAdmin(playerid, adminLogin) == falsereturn SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Вы не являетесь администратором");
    if(GetAdmin(playerid, adminLevel) < 6return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Вы не можете использовать данную команду");

    if(!IsPlayerConnected(params[1])) return SCM(playerid, 0xA3A3A3AA"[C20000]Ошибка[]C_GREY] Данный игрок не в сети!");
    if(!strlen(params[1]) || !strlen(params[2])) return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Введите: /makeadmin [ID игрока] [Уровень администратора 0-8]");

    new targetid = strval(params[1]);
    new level = strval(params[2]);

    if(level < 0 || level > 8return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Уровень администратора [0-8]!");

    format(string, sizeof(string), "SELECT `id` FROM `users` WHERE `name`='%s'", pname);
    mysql_tquery(mysqlHandle, string, "OnAdminCheckQuery""ii", playerid, level);

    return true;
}

forward OnAdminCheckQuery(playerid, level);
public OnAdminCheckQuery(playerid, level)
{
    new string[256];
    new pname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pname, sizeof(pname));

    if(cache_num_rows() == 0) {
        return SCM(playerid, 0xA3A3A3FF"[C20000]Ошибка[]C_GREY] Пользователь не найден в базе данных");
    }

    if(level == 0) {
        format(string, sizeof(string), "DELETE FROM `admins` WHERE `name`='%s'", pname);
        mysql_tquery(mysqlHandle, string);
    } else {
        format(string, sizeof(string), "REPLACE INTO `admins` (`name`, `password`, `level`) VALUES ('%s', '%s', %d)", pname, "somepassword", level);
        mysql_tquery(mysqlHandle, string);
    }

    format(string, sizeof(string), "UPDATE `users` SET `admin`=%d WHERE `name`='%s'", level, pname);
    mysql_tquery(mysqlHandle, string);

    InfoPlayer[playerid][pName] = level;
    format(string, sizeof(string), "Администратор %s изменил ваш уровень администратора на: %d", pname, level);
    SCM(playerid, 0xFFFFFFAA, string);

    return true;
}

 

Share this post


Link to post
  • 0

@D2DChat, не нужен столбец admin в таблице users – он вообще не имеет никакого смысла, это избыточность. Достаточно в таблице admins завести столбец для хранения идентификатора аккаунта, который и будет первичным и уникальным ключом для данной таблицы.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • AndryKrut007
      By AndryKrut007
      Добрых времени суток, наш проект активно ищет разработчиков в CRMP проект.
       
      Нам требуются:
       
      Pawn разработчик
       
      PR менеджер
       
      Разработчик лаунчера
       
      Управляющий разработчиками
       
      А также рассмотрим любые другие вакансии
       
      Писать: тг @derhid
    • August_Rothschild
      By August_Rothschild
      Всем привет , как заменять анимации в игре ? Имеется ввиду анимации танцев , как прочесть файлы с анимациями или как заменять определенную анимацию