D-Two - Documentation
  • Introduction
  • Liberté & Gratuité
  • Installation
  • Mises à jour
  • Dev - Application & Core
    • Introduction
    • Documentation
    • API
      • Components (View)
  • Dev - Plugins
    • Introduction
    • Créer un plugin
    • API
      • Events (Messages)
      • Base
      • View
      • Inputs
    • Tutorials
      • Multi Account
  • Dev - Theme
    • Introduction
  • Liste des Plugins
    • MultiAccount
    • WorldPathfinding
Powered by GitBook
On this page
  • Création du projet et import des dépendances
  • Création de la classe MultiAccount_Plugin
  • Création de la classe MultiAccountManager et MultiAccountController
  • Raccourcis pour appliquer un clique sur toutes les fenêtres
  • Raccourcis pour passer à la fenêtre Suivante / Précédente
  • Update de l'initiative
  • Compiler et Test le plugin
  1. Dev - Plugins
  2. Tutorials

Multi Account

PreviousTutorialsNextIntroduction

Last updated 11 months ago

Dans ce tutoriel je vais vous montrer comment refaire le plugin MultiAccount (pas totalement complet), en vous guidant pas-à-pas.

Avant toute chose, veuillez lire la partie "" et "", afin d'être plus à l'aise et savoir comment setup votre projet Visual Studio.

Création du projet et import des dépendances

  • Créer un nouveau projet Visual Studio portant le nom "Dtwo.Plugins.MultiAccount"

  • Importer les dll "Dtwo.API.Hybride, Dtwo.API.Retro, Dtwo.API.Dofus2, Dtwo.API.Inputs, Dtwo.Plugins"

Création de la classe MultiAccount_Plugin

using Dtwo.API;

public class MultiAccount_Plugin : Plugin
{
	public static MultiAccount_Plugin Instance { get; private set; }
	public MultiAccount_Plugin(PluginInfos infos, Assembly assembly) : base(infos, assembly)
	{
		Instance = this;
		MultiAccountManager.Init();
	}
}

Création de la classe MultiAccountManager et MultiAccountController

using Dtwo.API;

public static class MultiAccountManager
{
    private Dictionary<DofusWindow, MultiAccountController> m_accounts = new()
    public IReadonlyDictionary<DofusWindow, MultiAccountController> Accounts => m_accounts;

    public void Init()
    {
        // On s'abonne aux events OnDofusWindowStarted / Stopped
        DofusWindow.OnDofusWindowStarted += OnDofusWindowStarted;
        DofusWindow.OnDofusWindowStoped += OnDofusWindowStoped;
    }
     
     // Une fenêtre commence a être sniffé   
     private static void OnDofusWindowStarted(DofusWindow dofusWindow)
     {
         m_accounts.Add(dofusWindow, new MultiAccountController(dofusWindow))
     }

     // Une fenêtre n'est plus sniffé
     private static void OnDofusWindowStoped(DofusWindow dofusWindow)
     {
         m_accounts.Remove(dofusWindow);
     }
}
using Dtwo.API;

public class MultiAccountController
{
    public readonly DofusWindow DofusWindow;
    
    public MultiAccountController(DofusWindow dofusWindow)
    {
        DofusWindow = dofusWindow;
    }
}

Raccourcis pour appliquer un clique sur toutes les fenêtres

Créer une classe MultiClickManager

using Dtwo.API;
using Dtwo.API.Inputs;
using Dtwo.API.Inputs.Extensions;

public static class MultiClickManager
{
	private static bool m_isStarted;
	private static bool m_onMultiClick;

	public static void Start()
	{
		if (m_isStarted)
		{
			return;
		}
		
		// On s'abonne aux event de KeyUp
		InputKeyListener.Instance.KeyUp += OnKeyUp;
		
		// On écoute les cliques du milieu
		InputKeyListener.Instance.AddKey(0x04); // Middle click

		m_isStarted = true;
	}
	
	public static void Stop()
	{
		m_isStarted = false;
	}

	private static void OnKeyUp(int key)
	{
		if (m_onMultiClick)
		{
			// On est déjà en train d'appliquer des clics dans les autres fenêtres
			return;
		}
		
		if (key == Ox04) // Middle Click
		{
			OnMultiClick()
		}
	}

	public static void Stop()
	{
		m_isStarted = false;

		// On se désabonne de KeyUp, et on arrête d'écouter le clique du milieu
		InputKeyListener.Instance.KeyUp -= OnKeyUp;
		InputKeyListener.Instance.RemoveKey(0x04);
	}


	private static void OnMultiClick()
	{
		// On démarre un nouveau thread, pour ne pas bloquer l'application
		Task.Factory.StartNew(async () =>
		{
			m_onMultiClick = true;

			PInvoke.POINT pos = new PInvoke.POINT();
			
			// On récupère la position de la souris sur l'écran en px	
			PInvoke.GetCursorPos(out pos);
			
			// On récupère la position relative à la fenêtre sur la-quelle le clique a été fait
			// En l'occurence la fenêtre en premier plan.
			PInvoke.ScreenToClient(PInvoke.GetForegroundWindow(), ref pos);

			for (int i = 0; i < MultiAccountManager.Accounts.Count; i++)
			{
				var account = MultiAccountManager.Accounts.ElementAt(i).Value;
				
				// Initialization d'un click gauche aux coordonées indiquées
				ClickInfo clickInfo = new ClickInfo(pos.X, pos.Y, false);
				
				// On applique le clique sur cette fenêtre dofus
				// La position du clique sera relative à la nouvelle fenêtre
				// La taille de la fenêtre doit être la même que la fenêtre qui a reçu le clique original
				// On attend que le clique se finisse (Click down + Click Up)
				await account.DofusWindow.SendClick(clickInfo);

				// On attend un peu de temps avant de passer à la fenêtre suivante
				Thread.Sleep(API.Random.Range(250,500));
					
				if (m_isStarted == false)
				{
					// Si on a stop, on s'arrête là
					m_onMultiClick = false;
					return;
				}
			}


			m_onMultiClick = false;
		});
	}
}

Dans la classe MultiAccountManager

public void Init()
{
        // ...
        MultiClickManager.Start()
}

A l'étape où vous en êtes, si vous compilez et ajouter le plugin, vous devriez être capable d'appliquer des cliques sur toutes les fenêtres à l'aide du clique du milieu

Raccourcis pour passer à la fenêtre Suivante / Précédente

TODO

Update de l'initiative

Dans la classe MultiAccount_Plugin :

using Dtwo.API;
using Dtwo.API.Hybride

public class MultiAccount_Plugin : Plugin
{
	// ...
	
	// Un joueur rejoint le groupe
	[DofusEvent]
	public void OnPartyJoinMessage(DofusWindow dofusWindow, PartyJoinMessage message)
	{
		MultiAccountManager.OnPartyJoin(dofusWindow, message);
	}
	
	// Le groupe a été updaté (changement d'initiative, etc ...)
	[DofusEvent]
	public void OnPartyUpdateMessage(DofusWindow dofusWindow, PartyUpdateMessage message)
	{
		MultiAccountManager.OnPartyUpdate(dofusWindow, message);
	}
}

Dans la classe MultiAccountManager

// Un personnage a été ajouté au groupe
// L'évent est call pour toutes les fenêtres
public static void OnPartyJoin(DofusWindow dofusWindow, PartyJoinMessage message)
{
    foreach (var member in message.Members)
    {
        foreach (var account in m_accounts)
        {
            // On cherche a update seulement la fenêtre qui a reçu le message
            // Afin de ne pas répéter l'opération pour toutes les autres fenêtres
            if (account.DofusWindow.Character.Name != member.name)
                continue;
            
            // On update l'initiative
            account.UpdateInitiative((int)member.initiative);
            break;
        }
    }
    
    // On change l'ordre de la liste
    ReOrder();
}

// Le groupe a été update (initiative qui change, etc ...)
public static void OnPartyUpdate(DofusWindow dofusWindow, PartyUpdateMessage message)
{
    if (m_accounts.ContainsKey(dofusWindow) == false)
        return;
        
    var owner = m_accounts[dofusWindow];
    if (wnerController.IsLeader == false)
    {
        // OnPartyUpdate va être appellé pour chaque fenêtre,
        // On ne veut itérer qu'une seule fois
        // Donc on se base sur le leader
        return;
    }

    // Find the account with the same name
    foreach (var account in m_accounts)
    {
        // On cherche le joueur qui a été update
        if (account.Value.DofusWindow.Character.Name != message.MemberInformations.name)
            continue;

        // On update l'initiative
        account.Value.UpdateInitiative((int)message.MemberInformations.initiative);
        
        // On change l'ordre de la liste
        ReOrder();
        break;
    }
}

 public static void ReOrder()
 {
     // On applique l'ordre d'initiative
     m_accounts = m_accounts .OrderByDescending(x => x.Value.Initiative).ToDictionary(p => p.Key, p2 => p2.Value);
 }

Dans la classe MultiAccountController

// ...

public int Initiative { get; private set; }

public void UpdateInitiative(int val)
{
	Initiative = val;
}

Compiler et Test le plugin

A savoir que dans ce tutoriel nous avons vu le strict minimum, a presque aucun moment nous avons fait de gestion d'erreur. Vous n'avez plus cas compiler le plugin, et suivre les opérations dans "".

Introduction
Créer un plugin
Créer un Plugin