0
Awards
LV
0
 
44
Likes
184

Messages

tweky

BOSS DE BOSS
Staff member
Administrator
Moderator LCS
High Rollers
Joined
Jun 7, 2024
Reaction score
44
Points
28
Age
31
Website
minios.ro
Credits
2,932
Descriere: DiscordAPI este un modul AMX Mod X care expune API in Pawn pentru a hosta boti Discord pe serverul de Counter-Strike 1.6. Modulul foloseste libraria D++ care este un proiect open-source cu development activ pentru hostare boti Discord in C++. Prin pluginurile Pawn se pot hosta mai multi boti Discord pe serverul vostru. README.md de pe Github si fisierele .inc ofera descrieri detaliate despre cum se foloseste API-ul, deci puteti folosi AI pentru a va crea pluginurile. Developmentul pentru acest modul este activ si voi adauga si alte functionalitati.

Momentan sunt implementate urmatoarele functionalitati:
- Start/Stop bot
- Trimitere mesaje intr-un canal text
- Primire mesaje dintr-un canal text
- Posibilitatea de a trimite reply catre o interactiune text dintr-un canal text
- Hookuri pentru eventuri de server: cand un server este adaugat/scos.
- Posibilitatea de a luat in format JSON toate serverele din care face parte un bot.

In viitor se vor adauga mai multe functionalitati (preluare lista membrii, asignare grade pentru membrii direct de pe server si altele), insa am vrut sa scot aceasta versiune stabila.

API-ul si exemplele le puteti vedea in acest link
You do not have permission to view link Log in or register now.
sau direct in ZIP-ul pentru versiunea pe care o folositi pe server.

Pentru cei care nu stiu scripting sau nu au nevoie de functionalitati custom, am creat pluginuri care mai au ca scop si exemplu de utilizare al API-ului:

1. discord_bot.sma: Este pluginul care porneste botul de Discord, afiseaza mesaje in consola cand acesta este adaugat/scos dintr-un server de Discord. Acest plugin expune si comanda bot_guilds care afiseaza in consola toate serverele de Discord in care este adaugat botul ( , ). Configurarea se face in configs/discord_bot.cfg

*NOTE: Pluginul poate primi update-uri, va sugerez ca mereu sa verificati pluginurile de pe repository-ul Github
Source code:
Code:
#include <amxmodx>
#include <amxmisc>
#include <discordapi>
#include <json>

// Debug logs for library API
//#define DEBUG

#define IDENTIFIER "discord_bot"

#define PLUGIN_CONFIG "discord_bot.cfg"

#pragma semicolon 1

enum CVARS
{
    TOKEN[128]
}

new g_eCvar[CVARS];

public plugin_init()
{
    register_plugin("[DiscordAPI] Discord BOT", "0.5.1", "lexzor");

    bind_pcvar_string(
        create_cvar(
            "discord_bot_token",
            "INVALID_CVAR",
            FCVAR_PROTECTED | FCVAR_SPONLY | FCVAR_SERVER,
            "Discord bot token"
        ),
        g_eCvar[TOKEN],
        charsmax(g_eCvar[TOKEN])
    );

    register_concmd("bot_guilds", "bot_guilds");
}

public plugin_cfg()
{
    new szCfgDir[64];
    get_configsdir(szCfgDir, charsmax(szCfgDir));
    server_cmd("exec %s", fmt("%s/%s", szCfgDir, PLUGIN_CONFIG));
    server_exec();

    OnConfigExecuted();
}

OnConfigExecuted()
{
    if(!BotExists(IDENTIFIER))
    {
        if(!CreateBot(IDENTIFIER, g_eCvar[TOKEN]))
        {
            set_fail_state("Failed to create Discord BOT!");
            return;
        }
        
        new opt[Options];
        opt[LOG_LEVEL] = DEFAULT;
        opt[PRINT_EVENT_DATA] = false;
        formatex(opt[PREFIX], MAX_CONSOLE_PREFIX_LENGTH - 1, "[DiscordBOT]");
        SetBotOptions(IDENTIFIER, opt);

        log_amx("Bot %s created", IDENTIFIER);
    }
#if defined DEBUG   
    else log_amx("Bot %s does not exists", IDENTIFIER);
#endif

    if(!IsBotReady(IDENTIFIER))
    {
        if(!StartBot(IDENTIFIER))
        {
            set_fail_state("Failed to start Discord BOT!");
        }

        log_amx("Trying to start bot %s", IDENTIFIER);
    }
#if defined DEBUG   
    else log_amx("Bot %s already started", IDENTIFIER);
#endif
}

public OnBotReady(const identifier[])
{
    if(equal(identifier, IDENTIFIER))
    {
        log_amx("Bot %s started", IDENTIFIER);
    }
#if defined DEBUG
    else log_amx("OnBotReady received for %s, but it's not plugin's bot %s", identifier, IDENTIFIER);
#endif
}

public bot_guilds(id)
{
    new buffer[700];
    new count = GetGuilds(IDENTIFIER, buffer, charsmax(buffer));

    if(!count)
    {
        if(id == 0)
        {
            server_print("There are not any guilds to be displayed!");
        }
        else 
        {
            client_print(id, print_console, "There are not any guilds to be displayed!");
        }

        return PLUGIN_HANDLED;
    }

    if(id == 0)
    {
        server_print("Guilds: %s", buffer);
    }
    else 
    {
        client_print(id, print_console, "Guilds: %s", buffer);
    }

    return PLUGIN_HANDLED;
}

public OnGuildCreated(const identifier[], const guild_data[])
{
    if(!equal(identifier, IDENTIFIER))
    {
        return;
    }
#if defined DEBUG
    else log_amx("OnBotReady received for %s, but it's not plugin's bot %s", identifier, IDENTIFIER);
#endif

    new JSON:guild = json_parse(guild_data);

    if(guild == Invalid_JSON)
    {
        log_amx("Failed to parse OnGuildCreated guild data: %s", guild_data);
        return;
    }

    enum OnGuildCreatedData
    {
        Id[64],
        Name[64]
    }

    new eData[OnGuildCreatedData];

    json_object_get_string(guild, "id", eData[Id], charsmax(eData[Id]));
    json_object_get_string(guild, "name", eData[Name], charsmax(eData[Name]));

    log_amx("Bot %s has been added in guild %s (%s)", identifier, eData[Name], eData[Id]);
}

public OnGuildDeleted(const identifier[], const guild_data[])
{
    if(equal(identifier, IDENTIFIER))
    {
        return;
    }

    new JSON:guild = json_parse(guild_data);

    if(guild == Invalid_JSON)
    {
        log_amx("Failed to parse OnGuildCreated guild data: %s", guild_data);
        return;
    }

    enum OnGuildDeletedData
    {
        Id[64],
        Name[64],
        bool:Unavailable
    }

    new eData[OnGuildDeletedData];

    json_object_get_string(guild, "id", eData[Id], charsmax(eData[Id]));
    json_object_get_string(guild, "name", eData[Name], charsmax(eData[Name]));
    eData[Unavailable] = json_object_get_bool(guild, "unavailable");

    if(!eData[Unavailable])
    {
        log_amx("Bot has been added in guild %s (%s)", identifier, eData[Name], eData[Id]);
    }
    else 
    {
        log_amx("Server %s (%s) has become temporarly unavailable for bot %s", eData[Name], eData[Id], identifier);
    }
}

2. chat_relay.sma: Plugin folosit pentru a trimite si primi mesaje de pe un canal text. Configurarea se face in configs/discord_bot.cfg.

*NOTE: Pluginul poate primi update-uri, va sugerez ca mereu sa verificati pluginurile de pe repository-ul Github
Source code:
Code:
#include <amxmodx>
#include <amxmisc>
#include <json>
#include <discordapi>

#define IDENTIFIER "discord_bot"

#pragma semicolon 1

enum CVARS
{
    ID[64],
    CHANNEL[64],
    BLOCKED_MSGS_PREFIXES[64]
}

new g_eCvar[CVARS];

public plugin_init()
{
    register_plugin("[DiscordAPI] Chat Relay", "0.8.0", "lexzor");
    
    register_clcmd("say", "cmd_say");
    register_clcmd("say_team", "cmd_say");

    bind_pcvar_string(
        create_cvar(
            "discord_bot_id",
            "INVALID_CVAR",
            FCVAR_PROTECTED | FCVAR_SPONLY | FCVAR_SERVER,
            "Discord bot ID. Used to ignore messages from itself"
        ),
        g_eCvar[ID],
        charsmax(g_eCvar[ID])
    );

    bind_pcvar_string(
        create_cvar(
            "discord_bot_chat_relay_channel",
            "INVALID_CVAR",
            FCVAR_PROTECTED | FCVAR_SPONLY | FCVAR_SERVER,
            "Channel to send server chat messages"
        ),
        g_eCvar[CHANNEL],
        charsmax(g_eCvar[CHANNEL])
    );

    bind_pcvar_string(
        create_cvar(
            "discord_bot_chat_relay_blocked_msgs_prefixes",
            "INVALID_CVAR",
            FCVAR_PROTECTED | FCVAR_SPONLY | FCVAR_SERVER,
            "Chat messages prefixes to block (used for chat commands)"
        ),
        g_eCvar[BLOCKED_MSGS_PREFIXES],
        charsmax(g_eCvar[BLOCKED_MSGS_PREFIXES])
    );
}

public cmd_say(id)
{
    if(!IsBotReady(IDENTIFIER))
    {
        return PLUGIN_CONTINUE;
    }
    
    new command[64];
    read_argv(0, command, charsmax(command));

    new message[128];    
    read_args(message, charsmax(message));
    remove_quotes(message);
    trim(message);

    if(strlen(message) == 0)
    {
        return PLUGIN_CONTINUE;
    }

    if(equal(command, "say_team"))
    {
        return PLUGIN_CONTINUE;
    }

    new blockedMessagesPrefixes[128];
    copy(blockedMessagesPrefixes, charsmax(blockedMessagesPrefixes), g_eCvar[BLOCKED_MSGS_PREFIXES]);

    new prefix[16];
    while(blockedMessagesPrefixes[0] && strtok2(blockedMessagesPrefixes, prefix, charsmax(prefix), blockedMessagesPrefixes, charsmax(blockedMessagesPrefixes), ',') != -1)
    {
        if(strncmp(message, prefix, strlen(prefix)) == 0)
        {
            return PLUGIN_CONTINUE;
        }
    }

    new name[MAX_NAME_LENGTH + 1];
    get_user_name(id, name, charsmax(name));

    new discordMessage[128];
    formatex(discordMessage, charsmax(discordMessage), "[%s] %s: %s", get_user_team(id) == 1 ? "T" : "CT", name, message);

    SendMessageToChannel(IDENTIFIER, g_eCvar[CHANNEL], discordMessage);

    return PLUGIN_CONTINUE;
}

public OnChannelMessageCreated(const identifier[], const channel_id[], const event_data[])
{
    if(!equal(identifier, IDENTIFIER) || !equal(channel_id, g_eCvar[CHANNEL]))
        return;

    new JSON:jsonEvent = json_parse(event_data);

    if(jsonEvent == Invalid_JSON)
    {
        log_amx("Failed to parse raw json event from OnChannelMessageCreated.");
        return;
    }

    new JSON:author = json_object_get_value(jsonEvent, "author");

    new content[128];
    new authorName[MAX_NAME_LENGTH * 2];
    new authorId[64];
    
    json_object_get_string(author, "username", authorName, charsmax(authorName));
    json_object_get_string(jsonEvent, "content", content, charsmax(content));
    json_object_get_string(author, "id", authorId, charsmax(authorId));

    if(equal(authorId, g_eCvar[ID]))
    {
        goto cleanup;
    }

    new JSON:mentionsArray = json_object_get_value(jsonEvent, "mentions");
    new count = json_array_get_count(mentionsArray);

    if(count > 0)
    {
        enum MentionData
        {
            Username[MAX_NAME_LENGTH],
            Id[32],
        }

        new JSON:mention;

        for(new i = 0, data[MentionData], mentionString[64]; i < count; i++)
        {
            mention = json_array_get_value(mentionsArray, i);
            json_object_get_string(mention, "username", data[Username], charsmax(data[Username]));
            json_object_get_string(mention, "id", data[Id], charsmax(data[Id]));

            formatex(mentionString, charsmax(mentionString), "<@%s>", data[Id]);
            new const pos = strfind(content, mentionString);

            if(pos == -1)
            {
                continue;
            }

            replace(content, charsmax(content), mentionString, fmt("^4@%s^1", data[Username]));
        }
    
        json_free(mention);
    }

    new message[128];
    formatex(message, charsmax(message), "^4[Discord]^1 %s^4:^1 %s", authorName, content);
    client_print_color(0, print_team_default, message);
    server_print(message);
    
cleanup:
    json_free(author);
    json_free(jsonEvent);
}

Descarcare:
You do not have permission to view link Log in or register now.


Nume: DiscordAPI

Versiune: v1.0.0

Link oficial:
You do not have permission to view link Log in or register now.


Instalare:
Pentru instalare modul AMX Mod X, configurare pluginuri si configurare bot Discord, vizitati
You do not have permission to view link Log in or register now.


Poze:
chat_relay.sma:
Pentru orice problema legata de modul, folositi sectiunea Issue (sau PR) de pe Github.

Pentru orice problema legata de pluginuri, puteti lasa reply in topicul acesta, in PM sau pe Discord: lexzor#0630
 
shape1
shape2
shape3
shape4
shape5
shape6
Back
Top