damitz
Загрузка...
всем привет как делаf
Активный
- Тема Автор
- #1
Приветствую друзья, было нечем заняться, решил сделать систему репорта.
Зависимости: mdialog, MySQL R41-4.
При выходе игрока из сервера, все репорты, созданные им - удаляются.
Подключать:
Подключать ПОСЛЕ mysql и mdialog.
Функции:
Автовызываемые функции:
Готовый пример с использованием sscanf, pawn.cmd:
Готов к конструктивной критике. Надеюсь, если что-то не так, то вы объясните, в чём конкретно проблема. Надеюсь хоть кому-то будет полезна эта система.
Если возникла проблема, пишите в эту тему, отвечу по возможности.
Думаю, принимаю и предложения для возможного УЛУЧШЕНИЯ системы. Если будет время и желание - буду дополнять инклуд.
Зависимости: mdialog, MySQL R41-4.
При выходе игрока из сервера, все репорты, созданные им - удаляются.
Подключать:
Pawn:
#include <report.inc> // если в папке pawno/include.
#include "../папка/report.inc" // если в другой папке, отличной от pawno/include.
Подключать ПОСЛЕ mysql и mdialog.
Функции:
Pawn:
ConnectReportSystem(MySQL:sqlConnect); // Подключение системы к серверу.
AddReport(playerid, message[]); // Добавление репорта в БД.
OpenFirstReport(playerid); // Открывает диалог для ответа на репорт.
OpenReportList(playerid, page=1); // Открывает список ВСЕХ репортов, которые сейчас есть. Page можно не трогать. Page отвечает за страницу репортов, советую не выставлять, так как там всё само подставляется где нужно.
Автовызываемые функции:
Pawn:
OnAdminAnswerToReport(adminid, playerid, answer[], report[]); // Вызывается, когда админ успешно отвечает на репорт игрока через OpenFirstReport или OpenReportList. adminid - айди админа, playerid - айди игрока, написавшего в репорт, answer - сообщение админа, report - сообщение игрока.
OnAdminCancelAnswerReport(adminid, playerid, report[]); // Вызывается, когда админ нажимает X, или ничего не вписывает в поле ответа. adminid - айди админа, playerid - айди игрока, написавшего в репорт, report - сообщение игрока в репорт.
OnReportsDelete(playerid, count); // Вызывается, когда игрок выходит и все его репорты удаляются. Вызывается ТОЛЬКО если был удалён ХОТЯ БЫ один репорт. playerid - айди игрока, чьи репорты удаляются, count - количество удалённых репортов.
Готовый пример с использованием sscanf, pawn.cmd:
Pawn:
// Все дефайны, которые я использовал:
#define COLOUR_SERVER 0xFF6600FF
#define COLOUR_ERROR 0xCC0000FF
#define COLOUR_SYNTAX 0xAAAAAAFF
#define TAG "[SERVER]: {FFFFFF}"
#define ERR_TAG "[ERROR]: {FFFFFF}"
#define SYNTAX_TAG "[SYNTAX]: {FFFFFF}"
#define PlayerName(%0) pData[%0][pName] // Изменяете под себя на ту переменную, где у вас хранится имя.
#define REPORT_KD 60 // Можете изменить под себя если хотите другую задержку на репорт.
new AdminRepAnswerCount[MAX_PLAYERS]; // Создаю переменную, в которой буду считать количество репортов, на которые админ ответил.
new AdminRepCancelCount[MAX_PLAYERS]; // Создаю переменную, в которой буду считать количество репортов, на которые админ НЕ ответил.
new ReportCount = 0; // Создаю переменную, которая будет отвечать за хранение количества существующих репортов.
new ReportKD[MAX_PLAYERS] = {0, ...}; // Создаю переменную, в которой будет храниться КД на отправление репорта.
public OnGameModeInit(){
//...
dataBase = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_BASE); // подключение к БД.
ConnectReportSystem(dataBase); // Подключение системы репортов. ОБЯЗАТЕЛЬНО передавать параметром вашу переменную айди подключения к БД. В моём случае - dataBase.
//...
return 1;
}
public OnPlayerConnect(playerid){
ReportKD[playerid] = 0; // Сбрасываю КД на репорт при подключении игрока.
return 1;
}
cmd:report(playerid, params[]){
if(!pData[playerid][pLogged]) // Проверка на авторизацию
return SendClientMessage(playerid, COLOUR_ERROR, ERR_TAG"Вы не авторизованы!");
if(ReportKD[playerid] > gettime()){ // Проверка на КД использования команды.
static const err_kd[] = ERR_TAG"Попробуйте снова через %d секунд(-у/-ы).";
new str_kd[sizeof err_kd + (-2) + 3];
format(str_kd, sizeof str_kd, err_kd, ReportKD[playerid] - gettime());
SendClientMessage(playerid, COLOUR_ERR, str_kd);
return 1;
}
new message[128];
if(sscanf(params, "s[128]", message))
return SendClientMessage(playerid, COLOUR_SYNTAX, SYNTAX_TAG"Используйте /report <сообщение>");
ReportCount++;
static const fmt[] = TAG"Вы отправили сообщение в репорт: %s";
static const fmt_[] = TAG"Вы %d в очереди.";
new str[sizeof fmt + (-2) + 128 + 1];
new str_[sizeof fmt_ + (-2) + 4];
format(str, sizeof str, fmt, message);
format(str_, sizeof str_, fmt_, ReportCount);
SendClientMessage(playerid, COLOUR_SERVER, str);
SendClientMessage(playerid, COLOUR_SERVER, str_);
static const fmt1[] = "[REPORT]: {FFFFFF}Игрок %s(%d) отправил сообщение в репорт: %s";
static const fmt_1[] = "[REPORT]: {FFFFFF}Уже %d репорт(-а/-ов)!";
new str1[sizeof fmt1 + (-6) + MAX_PLAYER_NAME + 3 + 128 + 1];
new str_1[sizeof fmt_1 + (-2) + 11 + 1];
format(str1, sizeof str1, fmt1, PlayerName(playerid), playerid, message);
format(str_1, sizeof str_1, fmt_1, ReportCount);
foreach(new i : Player){ // Перебор циклом всех игроков
if(pData[i][pAdmin] < 1) continue; // Проверка на админа. Если не админ - скипаем.
SendClientMessage(i, 0xCC0000FF, str1);
SendClientMessage(i, 0xCC0000FF, str_1);
SendClientMessage(i, 0xCC0000FF, "[REPORT]: {FFFFFF}Используйте /rep чтобы ответить на репорт.");
}
AddReport(playerid, message); // Добавляем репорт в БД
return 1;
}
cmd:rep(playerid){
if(!pData[playerid][pLogged]) // Проверка на авторизацию
return SendClientMessage(playerid, COLOUR_ERROR, ERR_TAG"Вы не авторизованы!");
if(pData[playerid][pAdmin] < 1) // Проверка на админа
return SendClientMessage(playerid, COLOUR_ERROR, ERR_TAG"Недоступно!");
OpenFirstReport(playerid); // Открываем диалог ответа на репорт.
return 1;
}
cmd:replist(playerid){
if(!pData[playerid][pLogged]) // Проверка на авторизацию
return SendClientMessage(playerid, COLOUR_ERROR, ERR_TAG"Вы не авторизованы!");
if(pData[playerid][pAdmin] < 2) // Проверка на ур. админа
return SendClientMessage(playerid, COLOUR_ERROR, ERR_TAG"Недоступно!");
OpenReportList(playerid); // Открываю список ВСЕХ репортов.
return 1;
}
public OnAdminAnswerToReport(adminid, playerid, answer[], report[]){ // Когда админ ответил на репорт
//Форматирую сообщения и отправляю админу.
static const fmt_[] = "[REP-ANS]: {FFFFFF}Вы ответили на репорт игрока %s(%d): %s";
static const fmt_1[] = "[REP-ANS]: {FFFFFF}Сообщение от игрока: %s";
new str_[sizeof fmt_ + (-6) + MAX_PLAYER_NAME + 3 + 128 + 1];
new str_1[sizeof fmt_1 + (-2) + 128 + 1];
format(str_, sizeof str_, fmt_, PlayerName(playerid), playerid, answer);
format(str_1, sizeof str_1, fmt_1, report);
SendClientMessage(adminid, 0xFFFF00FF, str_);
SendClientMessage(adminid, 0xFFFF00FF, str_1);
//Добавляю количество ответов на репорт админу, и сообщаю ему общее количество отвеченных репортов.
AdminRepAnswerCount[adminid]++;
static const fmt_str[] = TAG"Количество репортов, на которые вы ответили за всё время: %d";
new str_fmt[sizeof fmt_str + (-2) + 11 + 1];
format(str_fmt, sizeof str_fmt, fmt_str, AdminRepAnswerCount[adminid]);
SendClientMessage(adminid, COLOUR_SERVER, str_fmt);
//Форматирую сообщение, после чего отправляю всем админам.
static const fmt[] = "[LOG]: {FFFFFF}Администратор %s(%d) ответил на репорт игрока %s(%d): %s";
static const fmt1[] = "[LOG]: {FFFFFF}Сообщение от игрока: %s";
new str[sizeof fmt + (-10) + MAX_PLAYER_NAME * 2 + 6 + 128 + 1];
new str1[sizeof fmt1 + (-2) + 128 + 1];
format(str, sizeof str, fmt, PlayerName(adminid), adminid, PlayerName(playerid), playerid, answer);
format(str1, sizeof str1, fmt1, report);
foreach(new i : Player){// Перебор всех игроков
if(pData[playerid][pAdmin] < 1) continue; // Проверка на админа. Если не админ - скипаю.
SendClientMessage(i, 0x00FFFFFF, str);
SendClientMessage(i, 0x00FFFFFF, str1);
}
//Форматирую сообщения и отправляю игроку, которому ответил админ.
static const fmt2[] = "[REP-ANS]: {FFFFFF}Администратор %s(%d) ответил Вам на репорт: %s";
static const fmt3[] = "[REP-ANS]: {FFFFFF}Ваше сообщение в репорт: %s";
new str2[sizeof fmt2 + (-6) + MAX_PLAYER_NAME + 3 + 128 + 1];
new str3[sizeof fmt3 + (-2) + 128 + 1];
format(str2, sizeof str2, fmt2, PlayerName(adminid), adminid, answer);
format(str3, sizeof str3, fmt3, report);
SendClientMessage(playerid, 0xFFFF00FF, str2);
SendClientMessage(playerid, 0xFFFF00FF, str3);
ReportCount--; // Убавляю количество репортов, чтобы правильно отображать 'очередь'.
return 1;
}
public OnAdminCancelAnswerReport(adminid, playerid, report[]){
//Форматирую сообщение, отправляю его админу, который не ответил на репорт.
static const fmt[] = "[REP]: {FFFFFF}Вы отказались отвечать на репорт от игрока %s(%d).";
static const fmt1[] = "[REP]: {FFFFFF}Сообщение игрока: %s";
new str[sizeof fmt + (-4) + MAX_PLAYER_NAME + 3 + 1];
new str1[sizeof fmt1 + (-2) + 128 + 1];
format(str, sizeof str, fmt, PlayerName(playerid), playerid);
format(str1, sizeof str1, fmt1, report);
SendClientMessage(adminid, 0xFFFF00FF, str);
SendClientMessage(adminid, 0xFFFF00FF, str1);
//Добавляю количество не отвеченных репортов, и сообщаю админу общее количество не отвеченных репортов.
AdminRepCancelCount[adminid]++;
static const fmt2[] = "[REP]: {FFFFFF}Количество репортов, на которые вы не ответили: %d.";
new str2[sizeof fmt2 + (-2) + 11 + 1];
format(str2, sizeof str2, fmt2, AdminRepCancelCount[adminid]);
SendClientMessage(adminid, 0xFFFF00FF, str2);
//Форматирую сообщение и отправляю всем админам.
static const fmt3[] = "[LOG]: {FFFFFF}Администратор %s(%d) отказался отвечать на репорт игрока %s(%d).";
static const fmt4[] = "[LOG]: {FFFFFF}Сообщение от игрока: %s";
new str3[sizeof fmt3 + (-8) + MAX_PLAYER_NAME*2 + 3*2 + 1];
new str4[sizeof fmt4 + (-2) + 128 + 1];
format(str3, sizeof str3, fmt3, PlayerName(adminid), adminid, PlayerName(playerid), playerid);
format(str4, sizeof str4, fmt4, report);
foreach(new i : Player){ //Перебор циклом всех игроков.
if(pData[i][pAdmin] < 1) continue; // Проверка на админа. Если не админ - скипаю.
SendClientMessage(i, 0x00FFFFFF, str3);
SendClientMessage(i, 0x00FFFFFF, str4);
}
// Форматиурю сообщения и отправляю игроку, которому админ НЕ ответил.
static const fmt5[] = "[REP]: {FFFFFF}Администратор %s(%d) отказался отвечать на Ваш репорт.";
static const fmt6[] = "[REP]: {FFFFFF}Ваше сообщение в репорт: %s";
new str5[sizeof fmt5 + (-4) + MAX_PLAYER_NAME + 3 + 1];
new str6[sizeof fmt6 + (-2) + 128 + 1];
format(str5, sizeof str5, fmt5, PlayerName(adminid), adminid);
format(str6, sizeof str6, fmt6, report);
SendClientMessage(playerid, 0xFFFF00FF, str5);
SendClientMessage(playerid, 0xFFFF00FF, str6);
ReportCount--; // Убавляю кол-во репортов, чтобы 'очередь' отображалась правильно.
return 1;
}
public OnReportsDelete(playerid, count){ // При удалении репортов игрока.
ReportCount-=count; // Убавляю переменную, чтобы 'очередь' отображалась корректно.
//Форматирую сообщение и сообщаю админам, что репорты игрока были проигнорированы.
static const fmt[] = TAG"Игрок %s(%d) вышел. Количество репортов игрока, на которые не ответили: %d.";
new str[sizeof fmt + (-6) + MAX_PLAYER_NAME + 3 + 11 + 1];
format(str, sizeof str, fmt, PlayerName(playerid), playerid, count);
foreach(new i : Player){ // Делаю перебор игроков циклом.
if(pData[i][pAdmin] < 1) continue; // Проверка на админа. Если не админ - скипаю.
SendClientMessage(i, COLOUR_SERVER, str);
//Тут можно в целом прибавлять переменную AdminRepCancelCount на += count, которая отвечает за неотвеченные репорты, но это по желанию.
}
return 1;
}
// Вы можете сохранять в базу данных те-же значения переменных AdminRepAnswerCount и AdminRepCancelCount, чтобы вести статистику.
Готов к конструктивной критике. Надеюсь, если что-то не так, то вы объясните, в чём конкретно проблема. Надеюсь хоть кому-то будет полезна эта система.
Если возникла проблема, пишите в эту тему, отвечу по возможности.
Думаю, принимаю и предложения для возможного УЛУЧШЕНИЯ системы. Если будет время и желание - буду дополнять инклуд.