From Ape Wiki
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);
- Ex:
- json_*


