Pré-requis

  • Savoir programmer dans le langage du bot, c'est-à-dire en PHP.
  • Avoir quelques connaissances en PHP-CLI, l'interface en ligne de commande de PHP (facultatif).
  • Connaître la base de la POO, et de l'implémentation de la POO en PHP (notamment la notion de variables publiques, privées, ainsi que l'héritage).
  • Connaître le principe de fonctionnement du bot (système de droits, et plugins, le reste est rappelé dans cette page).
  • Savoir les différentes commandes RCon du serveur (unique interface de dialogue avec le serveur).

Voilà, c'est tout ce que vous avez besoin de savoir pour programmer un plugin. Maintenant, on peut passer à la programmation.

Un plugin pour vous

FIXME

En gros décrire l'utilité du plugin_dev

Création de plugins

Créer un plugin pour le LeelaBot est assez simple. En effet, le bot possède un ensemble de fonctions et de variables afin de vous aider le plus possible à faire ce que vous voulez le plus facilement possible.

Par contre, il est quand même recommandé d'avoir certains pré-requis pour pouvoir créer un plugin pour le LeelaBot.

Base d'un plugin

le système de plugins du LeelaBot se base sur une structure en programmation évènementielle, et sur un modèle orienté objet. Dans ce système, chaque plugin est représenté par une classe, héritant d'une classe mère Plugin.

La base du plugin consiste en une simple classe vide, ainsi que son déclarateur, suivant toujours la même syntaxe :

class PluginNomDuPlugin extends Plugin
{
 
}
$this->plugins[$pluginName] = new PluginNomDuPlugin($main);

Note sur le déclarateur : Si vous avez besoin de mettre du code s'exécutant au chargement du plugin (via la méthode magique __construct()), vous devez penser à mettre comme premier paramètre $main, ainsi que de mettre en début de fonction :

$this->_main = &$main;

En ayant bien sûr pris le soin de déclarer en en-tête de votre plugin la variable privée $_main. Si vous n'avez pas besoin de la classe main dans votre plugin, vous pouvez passer cette note (quoique il est très difficile de faire un plugin sans la classe Main, qui contient toutes les méthodes d'accès au serveur, ainsi que la base complète des joueurs connectés…).

Normes du bot

Nommage : Les plugins sont nommés selon leurs nom de fichier dans les fichiers de configuration du bot, en UpperCamelCase pour les noms de classes et en lowerCamelCase pour les noms de méthodes. Pour les variables, il est conseillé de les nommer de la même manière que les méthodes, en lowerCamelCase. Il est aussi conseillé de préfixer vos variables privées par un underscore “_”, pour pouvoir ainsi les différencier des variables publiques directement.

Pour les différentes fonctions exécutées par les events (voir plus bas pour prendre connaissance du système des events), une syntaxe spéciale est aussi utilisée :

  1. routineAction() pour les routines, ou Action est un bref résumé (1-3 mots) de l'action effectuée par la routine
  2. SrvEventCommande() pour les events serveurs, où la commande est celle du serveur pour lequel l'event va répondre
  3. CmdEventCommande() pour les events utilisateurs, où la commande est la commande utilisateur déclenchant l'event (sans le !, interdit par PHP pour les noms de fonctions/méthodes et variables)

Plaçage des variables/fonctions : Les variables permanentes du plugin (configuration…) doivent être placée en haut de celui-ci, avant la déclaration de la première méthode, et privées si elles n'ont pas à être lues par d'autres plugins. Les méthodes quant à elles, pour des raisons de clarté, doivent être rangées en catégories (méthodes magiques, méthodes standard, routines, events serveur, events client).

Commentaires : le développeur doit s'efforcer de commenter son code (même si des fois j'oublie de commenter…), pour qu'il soit le plus possible compréhensible par les autres. Il ne faut bien sûr pas tomber dans l'excès en commentant toutes les lignes, il suffit de mettre un commentaire au début de chaque méthode afin de comprendre son utilité, et un commentaire par-ci par-là, aux endroits risquant d'être mal compris. Il est aussi recommandé de mettre en début de fichier les informations nécessaires si vous créez des structures peu compréhensible, ou si vous avez fait un travail de recherche sur le jeu qui peu être bénéfique aux autres développeurs (exemple : listage de tous les chiffres renvoyés pour un kill).

Commentaires spéciaux : Il est aussi conseillé de mettre, préfixé par le mot “TODO”, la liste des choses à faire sur votre plugin, ainsi que le mot “DELETE” avant des morceaux de codes que vous souhaitez supprimer plus tard.

Ancien système de gestion

L'ancien système de gestion (aujourd'hui obsolète, mais pouvant toujours être utilisé), repose sur un ensemble de trois méthodes décrivant trois niveaux d'exécution du code d'un plugin :

  • Le niveau Main, représenté par la méthode executeMain(). Il est exécuté à chaque “tour de boucle” du bot, permettant de définir des actions ne nécessitant pas d'action du serveur (par exemple, des temporisations). Il est recommandé de ne pas trop surcharger ce niveau d'exécution, ceci pouvant ralentir le bot.
  • Le niveau ServerCommand, représenté par la méthode executeServerCommand(). Il est exécuté à chaque fois que le serveur envoie une commande, ceci permettant au bot de réagir face à des commandes serveur, telles que ClientConnect:, ou Kill:. ne mettez pas les commandes client ici, car un autre niveau d'exécution a été fait spécialement à cet effet.
  • Le niveau ClientCommand, représenté par la méthode executeClientCommand(). Il est exécuté à chaque fois qu'un client envoie une commande préfixée par '!'.

Pour utiliser ces niveaux d'exécution, il vous suffit seulement de créer dans votre plugin une méthode publique ayant le nom d'une de celle décrite ci-dessus. Vous n'avez pas besoin de créer les méthodes qui ne vous serviront pas, elles sont incluses directement dans la classe héritée Plugin (et vides, bien entendu).

Ce système est adapté pour des plugins où celui-ci doit faire une seule grosse action, cela permet d'éviter de multiplier les fonctions pour faire une seule action (par exemple, le plugin IRC utilise ce système). En revanche, ce système n'est vraiment pas efficace dans le cas où plusieurs actions doivent être exécutées selon des commandes du serveur ou du client. En effet, pour gérer ce genre de cas, vous devrez coder tout le système permettant de vérifier les droits avant d'exécuter les commandes, ce qui est peu pratique pour gérer simplement des commandes.

C'est pourquoi le nouveau système de gestion a été fait.

Nouveau système de gestion

Le nouveau système de gestion, basé sur un système de programmation évènementielle (du côté du concepteur de plugin, bien entendu), vous permet de gérer simplement l'accès aux différentes informations nécessaires pour utiliser au mieux les capacités du bot.

Ce système vous décharge de la corvée de gérer les droits entre les commandes ou encore la séparation des commandes. Il reprend l'ancien système des 3 niveaux d'exécutions, mais en changeant le système afin que vous puissiez créer vos méthodes plus précisément, à l'unité, et ainsi clarifier votre code.

Ce système de gestion d'évènements se base sur 3 méthodes pour ajouter des évènements (un pour chaque niveau d'exécution bien entendu) :

  • Pour créer des méthodes du niveau Main, maintenant appelées routines (car elles sont tout le temps appelées, d'où le nom de routines), la méthode à utiliser est la méthode addRoutine(). Cette commande prend en paramètres le nom du plugin (tel que mentionné dans les fichiers de configuration), ainsi que le nom de la fonction à appeler.
  • Pour créer des méthodes du niveau ServerCommand, la méthode à appeler est la méthode addServerCommand(). Elle prend comme paramètres la commande à laquelle cet event doit réagir (avec les double-points, comme par exemple ClientConnect:, Kill:…), le nom du plugin à appeler, et enfin la méthode dudit plugin à appeler.
  • Pour créer des méthodes du niveau ClientCommand, la méthode à utiliser est la méthode addClientCommand(). Elle prend comme paramètres la commande sur laquelle réagir (avec le !, ce qui vous permet d'utiliser d'autres signes de ponctuation pour les différentier des autres, même si c'est déconseillé), le nom du plugin associé, la méthode dudit plugin à exécuter, et enfin le niveau de droits minimum requis pour l'exécuter.

Voilà pour la création d'events avec le nouveau système de gestion de commandes. La destruction d'events n'a pas encore été faite, mais cela ne saurait tarder.

Accéder à ces méthodes

Ces méthodes sont accessibles au même endroit qu'elles soient celles de l'ancien plugin, ou celles du nouveau plugin. Vous pouvez y accéder à partir de la classe plugin, elle-même contenue dans la classe main sous le nom de variable plugins. Par défaut, la référence vers la classe main dans votre plugin est contenue dans la variable privée _main. Voici un exemple de déclaration d'events, suivant la syntaxe conseillée :

//Déclarations des routines
$this->_main->plugins->addRoutine('plugindelamortquitue','routineKillEveryone');
$this->_main->plugins->addRoutine('plugindelamortquitue','routineSlapEveryone');
 
//Déclarations des events serveur
$this->_main->plugins->addServerEvent('Kill:','plugindelamortquitue','SrvEventKill');
$this->_main->plugins->addServerEvent('Exit:','plugindelamortquitue','SrvEventExit');
 
//Déclaration des events client
$this->_main->plugins->addClientEvent('!killme','plugindelamortquitue','CmdEventKillMe',0);
$this->_main->plugins->addClientEvent('!killall','plugindelamortquitue','CmdEventKillAll',10);

Données du bot/serveur

L'accès aux différentes données sur le serveur se fait via des variables publiques de la classe main (d'où la nécessité presque absolue d'utiliser la classe main pour faire un plugin convenable). Ils sont regroupés selon le type de données à laquelle vous souhaitez accéder :

  • Pour accéder aux informations générales sur le serveur (map, nom du serveur, paramètres divers et variés), vous pouvez les trouver dans la variable serverInfo (présentée sous la forme d'un Array). Pour connaître les clés, il suffit d'utiliser un print_r().
  • Pour accéder aux informations relatives aux clients, il faut utiliser la variable players. Les données sont classées dedans avec les clés suivantes :
0 : ID client
1 : GUID
2 : pseudo
9 : IP
10 : Team
11 : Level
  • Pour accéder aux compositions des équipes ainsi qu'au nombre de joueurs par équipe, les variables à utiliser sont les variables teams et teams_nb (celle-ci ne respectant pas les normes que je m'étais fixé). Les données sont rangées comme ceci :
Pour teams :
numéro de l'équipe : array( [id du joueur] => pseudo)

Pour teams_nb :
numéro de l'équipe : nombre de joueurs

Rappel des numéros d'équipe :
1 : Red
2 : Blue
3 : Spectator
  • Pour accéder à la commande envoyée par le serveur (en niveau ServerCommand et ClientCommand), la variable à utiliser est la variableserverCommand dans la classe main.
  • Pour accéder à l'ID du client (uniquement dans le niveau ClientCommand), la variable à utiliser est la variable clientID dans la classe main.
  • Pour accéder au message du client (uniquement dans le niveau ClientCommand), la variable à utiliser est la variable clientMsg dans la classe main.

Interface avec le jeu

Pour interfacer avec le serveur Urban Terror, vous n'avez qu'un seul et unique moyen : le RCon. Pour utiliser l'accès RCon au serveur, il vous faudra passer par la classe Q3Query, instanciée par l'objet query, à l'intérieur de la classe main. Vous pouvez bien sûr utiliser votre propre instance de Q3Query, afin de dialoguer avec un autre serveur par exemple.

Cette classe contient plusieurs méthodes pour accéder au serveur simplement. Il existe néanmoins des méthodes génériques pour entrer des commandes RCon pures.

Voici quelques exemples d'utilisation de cette classe, vraiment simple d'utilisation :

 
//Instanciation de Q3Query et connexion au RCon (inutile à faire dans le cas du serveur principal, elle est faite lors de la connexion)
 
$this->rconConnexion = new Q3Query('127.0.0.1',27961);
$this->rconConnexion->set_rconpassword('leelabot'); //Réglage du mot de passe
 
//Envoi d'une RCon directe, coupant le serveur principal
$this->_main->query->RCon('exit');
 
//Slap d'un joueur (ici, le pseudo est à mettre en entier)
$this->_main->query->slap('linkboss');
 
//Kick d'un joueur (pareil que pour le slap)
$this->_main->query->kick('linkboss');
 
//Affichage d'un message (cette fonction est préférable car elle découpe le message en parties, le serveur ne pouvant afficher plus de 133 caractère dans un message texte)
$this->_main->query->say('Bonjour, je suis LeelaBot !');
 
//Affiche un message à un certain joueur (pareil que pour say)
$this->_main->query->tell('linkboss','Bonjour toi, je suis LeelaBot !');
 
//Affiche un message en gros au milieu de l'écran
$this->_main->query->bigtext('Bonjour, je suis LeelaBot !');

IL y a évidemment d'autres méthodes, mais je ne vais pas toutes les détailler ici (si vous avez besoin de vous renseigner sur une méthode, référez-vous directement à la classe elle-même).

Pages liées

Suivant : Communiquer avec le site

Sommaire : Retour au sommaire

Précédent : Les plugins

creation_de_plugins.txt · Dernière modification: 2010/12/09 19:22 (édition externe)
 
 
©2008 Another cool website by 80KV