Emudofus / BehaviorIsManaged

Program simulating behaviors
GNU General Public License v3.0
31 stars 31 forks source link

Plugins System #7

Closed kesslerdev closed 11 years ago

kesslerdev commented 12 years ago

Salut, Je n'ai pas trouvé le moyen d'attacher un plugin a une connexion ( une classe non statique qui récupérerais les Messages de la connexion qui la instanciée, une instance par connexion) Ex: BotMITM => instancie gatheringManager du plugin GatheringPlugin gatheringManager récupère uniquement les Messages transmis par le BotMITM qui l'a instanciée

je n'ai pas trouvé dans de méthode adéquate dans MessageDispatcher

on peux toujours bidouiller le plugin pour faire un genre d'instance manager mais se ne serait pas propre

Timorem commented 12 years ago

Hm, on pourrait créer un nouveau dispatcher qui ferait office de filtre, ensuite au moment où tu recois BotCreatedMessage tu peux changer le Dispatcher du bot.

Après je ne vois pas trop l'intérêt de bind un plugin à un bot unique, le mieux est d'activer ou non les fonctionnalités.

EDIT : Hm, effectivement je viens d'y réfléchir et ce n'est pas évident. On pourrait changer les inscriptions des methodes handler qui actuellement sont statiques, et les lier au contraires aux dispatchers, c'est à dire que à chaque fois qu'on créer un dispatcher il va chercher les handlers on pourrait mettre à disposition des objets (i.g HandlersSubscriber) qui se chargerait de load les handlers de chaque assembly. Par exemple on aurait un HandlerSubscriber pour BiM, donc qui load toutes les assembly et un Subscriber de base pour chaque plugin qu'on pourrait surcharger pour faire des filtres.

Bref ça permet de controler les inscriptions à ce niveau mais selon moi il y a une méthode plus simple qui consiste à avoir un event BeforeDispatching(ref bool) dans la classe Dispatcher, le plugin alors s'inscrit à l'event et si le sender (l'objet Bot) n'est pas exemple pas dans une certaine liste alors il n'accepte pas le dispatching. Seul soucis c'est que ça ralenti le dispatching.

Après on peut voir ça selon un autre angle, le mieux ça reste d'abstraire un maximum le protocol, c'est à dire on utilise le moins possibles les messages. Par exemple pour un bot de récolte il faudrait juste savoir quand le joueur se déplace, arrete de se déplacer, commencer à récolter, arrête de récolter, quand il entre en combat etc. Tout ça seront géré dans l'objet PlayedCharacter avec des events (i.g StartMoving, StopMoving, StartInteraction, ...)

J'ai pas d'autres idées maintenant

kesslerdev commented 12 years ago

j'avais pensé personnellement:

Apres sa risque d'avoir beaucoup de messages non envoyées si par exmple on connecte 8 comptes avec 15 plugins par exemple, je pense que le meilleur moyen serait d'ajouter un nouveau Dictionary en incluant l'instance du sender sa permettrai du moins du coté du messageDispatcher(certes il faudra a la main faire un register au lieu d'utiliser la reflexion) un système réutilisable.

j’espère que je me suis fait comprendre si tu veux plus d'informations on peux se rejoindre sur l'IRC de Stump

Timorem commented 12 years ago

Ca casse la règle de la hiérarchie, seul l'Host sait qu'il y a des plugins, les autres ne doivent pas intérargir avec. Et puis ton système est un peu compliqué, ça réécrit un code de dispatch des messages internes au plugins, c'est un peu bête, autant faire quelque chose de générique à tout le programme.

(Je suis en vacances là, donc pas d'irc ^^)

kesslerdev commented 12 years ago

ou alors plus simple : on ajoute un champ sender dans MessageHandler et lors de l'envoi du message on verifie si un sender est précisé si oui il faut que le sender du MessageHandler soit identique au sender réel du message. Pour les methodes register j'ai opté pour l'ajout d'un argument a la méthode registerContainer(pourquoi ce choix ? car une classe statique ne pouvant "ecouter" les messages que d'une simple connexion ce n'est pas intéressant). du coté des plugins: toute classe non statique pour être disponible dans un plugin doit être dérivée de PluginClass (pour implémenter automatiquement le registerContainer et une methode Dispose()); dans le pluginManager un gestionnaire d'instance des PluginClass.

-Seul L'Host sait qu'il y a des plugins -Simple -réutilisable pour tout le programme

Timorem commented 12 years ago

MessageHandler est créé à partir de l'attribut, c'est juste un moyen de stockage en fait c'est pas censé être modifiable (tous les props sont private). On peut pas spécifier de délégué dans un attribut donc pas possible de le filtrer comme ça. Après j'ai pas très bien compris ta solution, à quoi servirait PluginClass ?

Le gros problème c'est qu'il est impossible de mettre un délégué dans un attribut, sinon on pourrait faire un système de filtre très facilement.

kesslerdev commented 12 years ago

c'est pour appeler automatiquement le registerContainer(this,bot); on peux toujours (mais c'est pas très propre) passer le nom du membre que l'on veut utiliser pour le filtre en type string et retrouver sa valeur via la reflexion

Timorem commented 12 years ago

Il faudrait plutot avoir une List, sinon le plugin fonctionnerait que pour un seul Bot x)

Timorem commented 12 years ago

On peut faire des classes statiques voir même instanciés qui serviraient de filtre avec une méthode bool ShouldHandle(Message msg) par exemple. On peut soit les cibler avec typeof() ou bien en faisant une sorte de FilterFactory qui bind le filtre avec un nom string. C'est plus propre que de faire de la réflexion directement. Le soucis c'est de faire un filtre générique pour les plugins (donc une instance par plugin) et de retrouver le filtre associé au plugin.

Je pense qu'il faudra "tricher" un peu avec de la réflexion pour déterminer le plugin peut être.

Torf commented 12 years ago

Au niveau de la dépendance des plugins, tu as déjà une idée du fonctionnement ?

Timorem commented 12 years ago

Oui ce sera plutot simple et automatique. Quand tu écris le plugin tu ajoutes les dépendances en références. Au moment de charger le plugin BiM détecte les références à d'autres plugins et essaye de les charger avant (il les mets en état "Attente de chargement de {0}"). Au niveau des plugins il y aura quelques modifications à faire, déjà faire une classe Settings qui servirai de configuration mais serait dépendant du bot actuelle. Càd que le fichier settings sera chargé au moment de charger le personnage. Ensuite avoir une propriété dans l'instance Bot qui permettrait de bind des données cette fois-ci dynamiques. Par exemple le plugin pour associer le nombre de monstres tués en 1 heure à un bot spécifique.

C'est les modifications que j'ai planifié au niveau des plugins

Timorem commented 12 years ago

Je cherchais beaucoup trop compliqué, il suffisait de penser à pouvoir définir un handler pour un Dispatcher unique (donc un bot par exemple) Ainsi tu peux associer une instance de handler au bot et l'enlever à tout moment, c'est par ce moyen qu'il faut gérer l'activation ou non d'un plugin pour un bot.