PDA

Просмотр полной версии : [Вопрос] Создание команды.



Johnny_Wallace
02.03.2017, 23:25
Доброго времени суток всем. Сегодня пришёл к Вам с парой вопросов и, почитав темы на форуме, убедился, что люди тут знающие сидят.
Я работаю с Pawn не так уж и давно, знаю достаточно мало, но всё же стараюсь пополнять знания.
На этот раз скачал мод и работаю в нём уже пару недель, чтобы уже окончательно более-менее разобраться в Pawn языке. Плагины, установленные в моде до меня - <zcmd> и <sscanf2>. Ими и будем пользоваться.

Итак, предыстории достаточно, к делу.

Я переписывал систему администрирования в моде и вырезал стандартную авторизацию /alogin, дабы создать другую. На данный момент это последнее, что осталось сделать по админ. командам, но и самое сложное для меня.
В моих планах было сделать команду /duty [пароль] (всего паролей будет 7, под каждый уровень администрирования) и здесь-то я и просел.
Если написание стандартных команд /ban, /offban, /hpall, /a, /admins, /setmp и подобное я сделал, то тут сложнее получилось.

Я перечитал достаточно информации на форумах и понял, что придется юзать bool или static const для хранения паролей (но это не точно) и реализовывать каждый пароль для своего уровня админки через switch. Примерно, обзаведясь этими данными, подумал, что всё проще простого, но... нет.

Смотрим код, что я намудрил.

Ко всем new (прикладываю два варианта, что использовал)


static const AdminDuty [7] =
{
3117896,
3937140,
9945800,
5464133,
9856641,
9286298,
1269818
};



И



new AdminDuty[1][7]=
{
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818}
};


То бишь эти переменные и будут хранить наши пароли.
Теперь команды.
Первая версия была с использованием static const и запрашиванием этих паролей через params[0], приравнивая их к AdminDuty[]. Но забыл, что подобное провернуть будет невозможно (но это не точно). Смотрим код.


CMD:duty(playerid,params[])
{
if(gLogAcc[playerid] == false) return 1; // Буду пояснять на первый раз за каждую строку. В данном случае это обычная проверка на авторизацию на сервере
if(PlayerInfo[playerid][pAdmin] < 1) return 1; // Тут всё и без того ясно
if(sscanf(params, "d", params[0])) return 1; // Используем params[0] как /duty params[0] (пароль), а затем приравниваем его (ниже)
if(params[0] == AdminDuty[]) // Здесь и сел, ибо как мне кажется подобное нельзя провернуть (я про выбор нужного пароля AdminDuty из тех, что мы прописываем в /duty [пароль] (но это не точно)).
{
gAdminLogged[playerid] = true; // Админ авторизация
//Оповещение об авторизации администратора в админ чат
}
return 1;
}

Вторая версия.
Пробовал использовать stock'и (здесь я static const и new AdminDuty в глобальных new временно закомментировал).
Ко всем командам:


CMD:duty(playerid, params[])
{
if(gLogAcc[playerid] == false) return 1;
if(PlayerInfo[playerid][pAdmin] < 1) return 1;
if(sscanf(params, "d", params[0])) return 1;
AdminDuty(playerid);
return 1;
}

К stock'ам:


stock AdminDuty(playerid)
{
Send(playerid, C_WHITE, "Вы ввели команду"); // намеренно добавил это чтобы проверить, а работает ли вообще такая версия. В итоге текст мне выводило, но ни авторизации, ни оповещения в админ чат не было (проверял со второго аккаунта с админой).
new adminpass[6][7]= // Фактически вырезал из слитого мода Arizona RP (Не реклама), но там лажа в том, что подобная функция (ниже)
// if(!GetString(adminpass[Pass_num][PlayerInfo[playerid][pAdmin]], inputtextsave)) return 1;
// просто не работала. Что-то там про "GetString" на Wiki пишут, типа не рабочая больше, а как сделать иначе - не догнал.
{
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818},
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818},
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818},
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818},
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818},
{3117896, 3937140, 9945800, 5464133, 9856641, 9286298, 1269818}
};
if(inputtext == PlayerInfo[playerid][pDostup])
{
gAdminLogged[playerid] = true;
//Оповещение об авторизации администратора в админ чат
}
return 1;
}


Пробовал брать старую версию /alogin'a в моде, но там беда в том, что в самой команде через ShowPlayerDialog идёт обращение к case в OnDialogResponse. Так как я не использую ShowPlayerDialog, то мне и делать нечего в этом case'е.

Также пытался найти хоть какую-либо подобную систему (всегда так делаю, когда не знаю как самому написать), затем разобрать её, понять смысл работы и сделать своё, самому. Однако, увы, как я понял, всех всегда устраивала обычная авторизация схожая с авторизацией на SAMP RP (не реклама) через ShowPlayerDialog и case в OnDialogResponse или же другая версия, когда админ.авторизация проходит автоматически при вводе пароля от аккаунта (как на ARP, к примеру != Реклама).
Однако я всё же нашёл пару подобных моментов, прикладываю:
http://pawno-info.ru/showthread.php?t=257148&attempt=1 // здесь в комментариях люди отписывались, что нужно юзать switch, а не создавать по 20 команд /duty. Однако как реализовать это я не знаю.
http://pro-pawn.ru/showthread.php?12247-%D0%B0%D0%B4%D0%BC%D0%B8%D0%BD-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D1%82%D1%8F&highlight=alogin+%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C // а вот здесь я брал за идею первую версию, но через данный способ можно сделать /duty лишь на один пароль, на один уровень админки. Я проверял, работает, но это не то, чего я добиваюсь.

Знаю, что сейчас могут вылезти особые личности кричащие мне "Мы должны за тебя всё сделать?" и т.д.
Однако поймите одно, что необязательно писать мне готовую команду. Мне нужна лишь та самая часть, отвечающая за проверку введенного пароля и авторизацию на нужный уровень через него или хотя бы просто порассуждать тут как я могу сам решить эту проблему с Вашей помощью.

BadPawn
03.03.2017, 04:10
Если бы мне это нужно было, то сделал бы как-то так:

static const __admin_alogin_password[3] = {
123,// Первый админ уровень
132,// Второй админ уровень
312 // Третий админ уровень
};

CMD:admin_login(playerid)
{
if(PlayerInfo[playerid][player_Admin] <= 0)
return 1;

ShowPlayerDialog(...); //открываем нужный нам диалог

return 1;
}

public OnDialogResponse(...)
{
//...
case admin_login:
{
if(!response)
return 1;

if(strval(inputtext) == __admin_alogin_password[PlayerInfo[playerid][player_Admin] - 1])
{
// Авторизируем и прочие действия
}
else
{
// Пароль не совпадает
}
}
//...
}

А вообще, лучше персонально каждому игроку генерировать рандомный пароль, после чего сообщать ему его и сделать какой-либо способ восстановления со сменой его. Как-то так. ))

Johnny_Wallace
03.03.2017, 09:35
Привет, спасибо, что откликнулся. Давай разбираться в твоём коде?
Итак, ты предлагаешь мне использовать static const для хранения паролей, а дальше в CMD через ShowPlayerDialog вызывать саму функцию команды в case на OnDialogResponse.
Однако, увы, как я и описывал в теме при её создании - подобная система меня не интересует. Написание авторизации через SPD и ODR, создание и восстановление паролей уже есть в паблике тысячами темами от людей, что каждый присваивает себе её авторство.
Меня очень заинтересовал данный вид авторизации, а именно через саму команду. То бишь ты вводишь: /duty [пароль один из 7] и сервер, прочитав этот пароль, уже авторизовывает тебя под уровнем админки, для которого он предназначен. Без ShowPlayerDialog и, возможно, без OnDialogResponse (но это не точно).
Ход событий, как это должно происходить.


1) пишем в чат: "/duty 9856641"
2) получаем от сервера админ авторизацию на наш уровень и это в чат: "[A] %s вошёл в админ панель [%d lvl] || IP: [%s] | Reg-IP: [%s]"

Как это выглядит в игре (прикрепляю фрапс свой старый)


https://www.youtube.com/watch?v=HPeIERapfUc&feature=youtu.be
Что мы видим на фрапсе? Мне выдают 5 уровень, при этом никакие пароли мне не сообщаются, не выдаются и не нужно регистрировать свой личный пароль. В ЛС мне лишь указывают где брать пароли и всё.

https://pp.userapi.com/c837225/v837225924/244cb/JTs1eKJYlzg.jpg
https://pp.userapi.com/c837225/v837225924/244d4/hRvFNcPpM0U.jpg

А затем, введя пароль от своей админки, я авторизовываюсь на сервере и мне доступно всё, как и показано на фрапсе (мут снял себе).

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

А если по делу, то нужно создавать хранение паролей, команду, а затем писать систему авторизации на switch либо в (forward) public, либо в stock (но это не точно).

123
03.03.2017, 12:50
static const AdminDuty [7] =
{
3117896,
3937140,
9945800,
5464133,
9856641,
9286298,
1269818
};

CMD:duty(playerid, params[])
{
if(!PlayerInfo[playerid][pAdmin])
return 1;

if(sscanf(params, "d", params[0]))
return 1;

if(params[0] == AdminDuty[PlayerInfo[playerid][pAdmin] - 1])
gAdminLogged[playerid] = true;

return 1;
}

Johnny_Wallace
03.03.2017, 14:43
Привет, спасибо, что откликнулся.
Я обязательно проверю твою версию и уже вижу, что должно вроде бы сработать.
Однако, как мне кажется, введя любой из этих паролей ты просто авторизуешься под уровнем админки, что прописан у тебя в БД.
Возможно ли в static const приравнять сейчас каждый из паролей к определённому уровню админки? Чтобы, допустим, введя пароль от 3-го уровня, а у тебя 4-у по БД, ничего не происходило.

123
03.03.2017, 15:02
Привет, спасибо, что откликнулся.
Я обязательно проверю твою версию и уже вижу, что должно вроде бы сработать.
Однако, как мне кажется, введя любой из этих паролей ты просто авторизуешься под уровнем админки, что прописан у тебя в БД.
Возможно ли в static const приравнять сейчас каждый из паролей к определённому уровню админки? Чтобы, допустим, введя пароль от 3-го уровня, а у тебя 4-у по БД, ничего не происходило.

Это учтено. В массиве пароли идут от первого уровня к последнему (следует это учесть, если уровней сейчас больше 7, тогда будет выход за пределы массива), если ввести пароль не от своего уровня, ничего не произойдет.

Johnny_Wallace
03.03.2017, 15:12
Благодарю, обязательно попробую всё, что ты написал.
Модераторы, тему пока что не закрывайте.

Johnny_Wallace
04.03.2017, 12:50
Отлично, всё как и задумывалось. Команда работает на "ура".
По сути, я просто недоработал одну строчку из своей первой версии. Буду знать.
Закрыто.