From Ape Wiki

Jump to: navigation, search

Contents

[edit] Modules de serveur

Un module du serveur est une librairie chargée en mémoire partagée au lancement du serveur.
Les modules permettent d'agir sur :

  • Les commandes utilisateurs
    • Ajouter des commandes utilisateurs
    • Supprimer des commandes utilisateurs
    • Altérer des commandes utilisateurs
  • Les évènements
    • Hooker des évènements (via des callbacks)
    • Stoper des évènements
    • Altérer des évènements

[edit] Squelette

[edit] En-têtes

#include <stdio.h>
 
#include "plugins.h"
#include "global_plugins.h"
 
#define MODULE_NAME "helloworld" // Unique identifier

[edit] Les deux structures de base

  • Structure relative aux informations du modules (définie en début de code) :

static ace_plugin_infos infos_module = {
	"HelloWorld", 		// Module Name
	"0.01",			// Module Version
	"Anthony Catel",	// Module Author
	"helloworld.conf"	// Config file (from ./bin/) (can be NULL)
};

Le dernier élément définit un fichier de configuration placé dans le dossier ./bin (facultatif)

  • Structure définissant les évènements à "hooker" (définie en fin de code avant l'intitialisation du monde) :

static ace_callbacks callbacks = {
	helloworld_adduser,		/* Called when new user is added */
	NULL,				/* Called when a user is disconnected */
	NULL,				/* Called when new chan is created */
	NULL,				/* Called when a user join a channel */
	NULL,				/* Called when a user leave a channel */
	NULL,				/* Called at each ticks and with a subuser param */
};

A l'heure actuelle APE compte 5 callbacks hookable par le serveur mais prévoie dans le futur de pouvoir en définir de nouveau.

[edit] Point d'entrée

Le point d'entrée est une fonction appelée au chargement du module :

static void init_module(acetables *g_ape) // Called when module is loaded (passed to APE_INIT_PLUGIN)
{
	/* Print "foo" key from helloworld.conf */
	printf("Helloworld loaded ;-) [Conf foo : %s]\n", READ_CONF("foo"));
 
	/* Adding a new raw GET /?HELLOWORLD&[SESSID]&[ANTICACHE] */
	register_raw("HELLOWORLD", 1, raw_helloworld, NEED_SESSID, g_ape);
}

Voir aussi register_raw

[edit] Initialisation

APE_INIT_PLUGIN(MODULE_NAME, init_module, callbacks)

[edit] Callbacks

APE appelle les différents callbacks définis dans les modules AVANT l'exécution de la fonction originale permettant donc à un module d'altérer, stopper, ou simplement intercepter un appel.

[edit] Principes de base

Prenons l'exemple défini dans la rubrique plus haut.
Le module défini un callback pour adduser. Le module doit définir une fonction ayant un prototype similaire à l'original.
La liste des prototypes peut être consultée dans ./modules/plugins.h

Exemple :

static USERS *helloworld_adduser(unsigned int fdclient, char *host, acetables *ace_tables)
{
	/*								*/
	/* Everything put here will be executed BEFORE the user has been added 	*/
	/*								*/
 
 
	/* Call parent function (can be another plugin callback) */
	USERS *n = adduser(fdclient, host, ace_tables);
 
 
	/*								*/
	/* Everything put here will be executed AFTER user has been added 	*/
	/*								*/
 
	if (n == NULL) {
		return NULL;
	}
	printf("[Helloworld !] => %s user added\n", n->pipe->pubid);
 
	/* Parent result must be returned (or NULL) */
	return n;	
}


Plusieurs possibilités s'offrent à vous :

  • Appeler la fonction originale (ici adduser) ET retourner sa valeur.
  • Ne pas appeler la fonction originale, retourner NULL et ainsi stopper toute propagation.
  • Ne pas appeler la fonction originale, construire vous même la valeur et la retourner (voir incompatibilités entre modules)


À noter que quand vous appelez la fonction originale, c'est peut-être celle d'un autre module qui sera appelée (récursivité entre modules).

[edit] Commandes utilisateurs

Les modules vous permettent d'ajouter des commandes utilisateurs de manière très simple grâce à la fonction register_cmd.
On enregistre généralement une commande utilisateur au chargement du plugins.

Cette fonction a besoin de 5 paramètres :

  • Le nom de la commande
  • Le nombre de paramètres (En comptant le sessid)
  • La fonction à appeler
  • Ce paramètre définie si l'utilisateur doit être logué (NEED_NOTHING / NEED_SESSID)
  • La structure globale de APE (g_ape)

Exemple :

register_cmd("HELLOWORLD", 1, raw_helloworld, NEED_SESSID, g_ape);

Le prototype de la fonction à appeler doit être le suivant :

static unsigned int raw_helloworld(callbackp *callbacki)

La structure callbackp est définie et remplie comme suit :

struct _callbackp
{
	int nParam;			// Nombre de paramètres
	char **param;			// Tableau contenant les paramètres
	unsigned int fdclient;	// File descriptor du socket client
	struct USERS *call_user;	// Structure de l'utilisateur (si NEED_SESSID)
	char *host; 			// Sur quelle Host est connectée l'utilisateur
 
	acetables *g_ape; 		// Structure globale de APE
};

Le structure USERS est définie dans users.h
Une liste complète d'exemples se trouve dans raw.c

[edit] Fonctions utiles

  • send_msg(USERS *, char *msg, char *RAW)
  • send_error(USERS *, char *msg)
  • send_msg_channel(CHANNEL *, char *msg, char *RAW)
  • send_msg_sub(subuser *sub, char *msg, char *RAW) (Voir sub users)
  • add_property_str(extend **entry, char *key, char *val)
    • Ex: add_property_str(&user->properties, "name", nick);
  • json_*