ircv3 / ircv3-ideas

46 stars 3 forks source link

Server favicon of sorts #123

Open ValwareIRC opened 4 months ago

ValwareIRC commented 4 months ago

Perhaps a nice idea for a server to provide a favicon for the client to display somewhere appropriate like the server window icon or cough like discord down the left hand side =]]] cough

delthas commented 4 months ago

Means

I like ISUPPORT best.

Naming

I like ICON best.

SadieCat commented 4 months ago

I proposed this as an ISUPPORT token a while back but I don't think it got any traction.

emersion commented 4 months ago

Previous discussion: https://github.com/ircv3/ircv3-ideas/issues/64

ValwareIRC commented 4 months ago

Since I like the ISUPPORT choice the best, here's some concept code of implementing it in UnrealIRCd real quick

/* === Configuration === */
favicon {
    host 'https://example.com/favicon.svg";
}
/** === Module Information ===
 * 
 * NAME: FAVICON
 * LICENCE: GPLv3 or later
 * COPYRIGHT: Ⓒ 2024 Valerie Pond
 * 
*/
#include "unrealircd.h"

#define CONF_FAVICON "favicon"

/* FAVICON config struct */
struct
{
    char *isupport_line;
    MultiLine *hosts;
    unsigned short int has_hosts;
} cfg;

int FAVICON_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
int FAVICON_configrun(ConfigFile *cf, ConfigEntry *ce, int type);
void setconf(void);
void freeconf(void);

ModuleHeader MOD_HEADER
  = {
    "third/favicon",
    "1.0",
    "FAVICON support",
    "Valware",
    "unrealircd-6",
};

MOD_TEST()
{
    setconf();
    HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, FAVICON_configtest);
    return MOD_SUCCESS;
}

MOD_INIT()
{
    HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, FAVICON_configrun);
    return MOD_SUCCESS;
}

MOD_LOAD()
{
    ISupport *is;
    if (!(is = ISupportAdd(modinfo->handle, "FAVICON", cfg.isupport_line)))
        return MOD_FAILED;
    return MOD_SUCCESS;
}

MOD_UNLOAD()
{
    freeconf();
    return MOD_SUCCESS;
}

void setconf(void)
{
    memset(&cfg, 0, sizeof(cfg));
    cfg.has_hosts = 0;
    safe_strdup(cfg.isupport_line,"");
}

void freeconf(void)
{
    freemultiline(cfg.hosts);
    cfg.has_hosts = 0;
    safe_free(cfg.isupport_line);
    memset(&cfg, 0, sizeof(cfg));
}

int FAVICON_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
{
    int errors = 0;
    ConfigEntry *cep;
    freeconf();
    setconf();
    if (type != CONFIG_MAIN)
        return 0;

    if (!ce || !ce->name)
        return 0;

    if (strcmp(ce->name, CONF_FAVICON))
        return 0;

    for (cep = ce->items; cep; cep = cep->next)
    {
        if (!cep->name)
        {
            config_error("%s:%i: blank %s item", cep->file->filename, cep->line_number, CONF_FAVICON);
            ++errors;
            continue;
        }
        if (!strcasecmp(cep->name, "host"))
        {
            if (!BadPtr(cep->value))
                cfg.has_hosts = 1;

            else
                config_error("%s:%i: Empty host at %s::%s", cep->file->filename, cep->line_number, CONF_FAVICON, cep->name);

            continue;
        }

        // Anything else is unknown to us =]
        config_warn("%s:%i: unknown item %s::%s", cep->file->filename, cep->line_number, CONF_FAVICON, cep->name); // So display just a warning
    }

    *errs = errors;
    return errors ? -1 : 1;
}

int FAVICON_configrun(ConfigFile *cf, ConfigEntry *ce, int type)
{
    ConfigEntry *cep;
    char buf[BUFSIZE] = "\0";

    if (type != CONFIG_MAIN)
        return 0;

    if (!ce || !ce->name)
        return 0;

    if (strcmp(ce->name, "favicon"))
        return 0;

    for (cep = ce->items; cep; cep = cep->next)
    {
        if (!cep->name)
            continue;

        if (!strcmp(cep->name, "host"))
            addmultiline(&cfg.hosts, cep->value);

    }

    for (MultiLine *m = cfg.hosts; m; m = m->next)
    {
        strlcat(buf,m->line, sizeof(buf));
        if (m->next)
            strlcat(buf,"\\x20",sizeof(buf));
    }
    if (strlen(buf))
        safe_strdup(cfg.isupport_line, buf);

    return 1; // We good
}
ValwareIRC commented 3 months ago

Here's an mIRC script which implements a bit of a lazy ICON support.

The script simply takes the image and applies it to the corner of the Status/Server window.