Система репорта

damitz

всем привет как делаf
Активный
Статус
Оффлайн
Сообщения
649
Лайки
289

10

месяц на сайте

Приветствую друзья, было нечем заняться, решил сделать систему репорта.
Зависимости: 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, чтобы вести статистику.

Готов к конструктивной критике. Надеюсь, если что-то не так, то вы объясните, в чём конкретно проблема. Надеюсь хоть кому-то будет полезна эта система.

Если возникла проблема, пишите в эту тему, отвечу по возможности.

Думаю, принимаю и предложения для возможного УЛУЧШЕНИЯ системы. Если будет время и желание - буду дополнять инклуд.
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху