Sari la conținut

Postări Recomandate

Postat

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 https://github.com/lexzor/amxmodx-disco ... /scripting 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 (https://imgur.com/EiPZHHr, https://imgur.com/aSGRpBK). 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:

 

Spoiler
#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:

 

Spoiler
#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: Link catre ultima versiune stabila!

Nume: DiscordAPI

Versiune: v1.0.0

Link oficial:  https://github.com/lexzor/amxmodx-discord-api

Instalare:
Pentru instalare modul AMX Mod X, configurare pluginuri si configurare bot Discord, vizitati https://github.com/lexzor/amxmodx-discord-api

Poze:
chat_relay.sma:   https://imgur.com/a/LuuQoC5 

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

Vizitator
Acest topic este acum închis pentru alte răspunsuri.
  • Navigare recentă   0 membri

    • Nici un utilizator înregistrat nu vede această pagină.
×
×
  • Creează nouă...

Informații Importante

Termeni de Utilizare & Politică Intimitate