C# Client qui prend le pas sur un autre..

Inscrit
10 Février 2020
Messages
19
Reactions
1
#1
Bonjour,

J'essaye de trouver le meilleur système MITM pour Dofus entre optimisation, légèreté et rapidité. Pour cela j'utilise les sources de RaidBots car elles sont à peu près "à jour" et que le fonctionnement répond à mes critères...

Mais je rencontre un soucis, quelque chose qui m'échappe, j'ai beau relire mon code et essayer des trucs je vois pas l'erreur.
Sur un seul compte ça fonctionne très bien, mais dès que je connecte un deuxième compte, le compte numéro un cesse de "visuellement" communiquer avec le serveur D2 car je vois encore les messages client>serveur de mon client perdu mais sur la fenetre D2 rien ne s'affiche, rien ne bouge au déplacement.

C'est vraiment très étrange, si quelqu'un peut m'aider je vous laisse ci-joint mes classes gérant la partie socket de mon programme.
Et je sais pas si le créateur de RaidBot traine encore ici mais je tiens à le remercier d'avoir mis ses sources en publicet qui comme beaucoup, m'ont permis d'avancé dans cet univers et d'aimer la programmation.

Ps: Si vous trouvez des erreurs autre que mon problème ou des moyens d'optimiser le projet n'hésitez pas à m'en parler sur le topic. Aussi, si j'arrive à réussir corriger moi même le problème je mettrait la solution ici + à l'aboutissement de mon projet, je posterai les sources ici en n'oubliant pas de citer les différents auteurs qui m'ont permis de le réaliser. Le projet consiste en un assistant pour multi-comptes (déplacements, quêtes, invitations groupes, échanges, changement automatique de fenêtre...)

Serveur
C#:
 class Server
    {
        #region Properties
        public static Server Default = new Server();
        private Socket Listener;
        public bool Runing { get; set; }
        #endregion

        #region Evenements
        public delegate void ConnectionAcceptedDelegate(object sender, Socket acceptedSocket);
        public event ConnectionAcceptedDelegate ConnectionAccepted;
        private void OnConnectionAccepted(Socket client)
        {
            if (ConnectionAccepted != null)
                ConnectionAccepted(this, client);
        }
        #endregion

        #region Constructeur
        public Server()
        {
            if (Runing)
            {
                Runing = false;
                Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            }
        }
        #endregion

        #region Méthode Publique
        public void Start(short Port)
        {
            if (!Runing)
            {
                Runing = true;

                Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Listener.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), Port));

                Listener.Listen(5);
                Listener.BeginAccept(AcceptCallback, Listener);

                Console.WriteLine("Server say> Le serveur est en écoute.");
                Console.WriteLine("Server say> Le master est: [" + Config.Master + "] La version du logiciel est: [" + Config.Version + "]" );

            }
        }

        public void Listen()
        {
            Listener.BeginAccept(AcceptCallback, Listener);
        }
        #endregion

        #region Méthode Privée
        private void AcceptCallback(IAsyncResult res)
        {
            Console.WriteLine("Server say> Nouveau client accepté.");

            if (Runing)
            {
                Socket listener = (Socket)res.AsyncState;
                Socket acceptedSocket = listener.EndAccept(res);

                listener.BeginAccept(AcceptCallback, listener);

                OnConnectionAccepted(acceptedSocket);
            }
        }
        #endregion
    }
Client
C#:
class Client
    {
        #region Properties
        private Socket _Socket;

        private Byte[] ReceiveBuffer;
        private Byte[] SendBuffer;

        private const int BufferSize = 8192;

        private Buffer CurrentMessage;
        private BigEndianReader Buffer;

        public Latency Latency { get; private set; }
        public bool Runing { get; set; }
        public bool IsLocal { get; set; }
        #endregion

        #region Constructeur
        public Client()
        {
            Init();
        }

        public Client(Socket socket, bool isLocal)
        {
            IsLocal = isLocal;
            Init();

            Start(socket);
        }
        #endregion

        #region Méthode Publique
        public void Start(Socket sock)
        {
            Latency = new Latency();
            Runing = true;

            _Socket = sock;
            _Socket.BeginReceive(ReceiveBuffer, 0, BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), _Socket);
        }

        public void Start(IPAddress address, int port)
        {
            Latency = new Latency();

            _Socket.BeginConnect(address, port, new AsyncCallback(ConnectionCallback), _Socket);
        }

        public void Stop()
        {
            _Socket.BeginDisconnect(false, DisconnectCallback, _Socket);
        }

        public void Send(Buffer message, bool withCounter)
        {
            BigEndianWriter Writer = new BigEndianWriter();
            byte typeLen;

            if (message.Data.Length > 65535)
                typeLen = 3;
            else if (message.Data.Length > 255)
                typeLen = 2;
            else if (message.Data.Length > 0)
                typeLen = 1;
            else
                typeLen = 0;

            Writer.WriteShort((short)(message.MessageId << 2 | typeLen));
            if (withCounter)
                Writer.WriteUInt(message.Count);

            switch (typeLen)
            {
                case 0:
                    break;
                case 1:
                    Writer.WriteByte((byte)message.Data.Length);
                    break;
                case 2:
                    Writer.WriteShort((short)message.Data.Length);
                    break;
                case 3:
                    Writer.WriteByte((byte)(message.Data.Length >> 16 & 255));
                    Writer.WriteShort((short)(message.Data.Length & 65535));
                    break;
                default:
                    break;
            }

            Writer.WriteBytes(message.Data);
            Send(Writer.Data);
        }

        public void Send(byte[] data)
        {
            Latency.Send();

            if (Runing)
            {
                if (data.Length == 0)
                    return;

                SendBuffer = data;

                _Socket.BeginSend(SendBuffer, 0, SendBuffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), _Socket);
            }else
                Console.WriteLine("Socket say> Send " + data.Length + " bytes but not runing");
        }
        #endregion

        #region Méthode Privée
        private void Init()
        {
            Buffer = new BigEndianReader();
            ReceiveBuffer = new byte[BufferSize];
            Latency = new Latency();

            _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        private void Threat()
        {
            if (CurrentMessage == null)
                CurrentMessage = new Buffer();

            if(CurrentMessage.Build(Buffer, IsLocal))
            {
                OnDataReceived(new DataReceivedEventArgs(CurrentMessage));

                CurrentMessage = null;
                Latency.Update();

                Threat();
            }
        }

        private void ConnectionCallback(IAsyncResult res)
        {
            Runing = true;

            Socket client = (Socket)res.AsyncState;
            client.EndConnect(res);

            if (client.Connected)
            {
                client.BeginReceive(ReceiveBuffer, 0, BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), client);
                
                OnConnected(new ConnectedEventArgs());
            }
            else
            {
                OnDisconnected(new DisconnectedEventArgs());
            }
        }
        private void DisconnectCallback(IAsyncResult res)
        {
            Runing = false;

            Socket client = (Socket)res.AsyncState;
            client.EndDisconnect(res);

            OnDisconnected(new DisconnectedEventArgs());
        }
        private void ReceiveCallback(IAsyncResult res)
        {
            Socket client = (Socket)res.AsyncState;

            if (Runing)
            {
                int BytesRead = 0;
                BytesRead = client.EndReceive(res);

                if(BytesRead == 0)
                {
                    Runing = false;
                    OnDisconnected(new DisconnectedEventArgs());
                    return;
                }

                Byte[] Data = new byte[BytesRead];
                Array.Copy(ReceiveBuffer, Data, BytesRead);

                Buffer.Add(Data, 0, Data.Length);
                Threat();

                client.BeginReceive(ReceiveBuffer, 0, BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), client);
            }else
                Console.WriteLine("Socket say> Receive data but not running");
        }

        private void SendCallback(IAsyncResult res)
        {
            if (Runing)
            {
                Socket client = (Socket)res.AsyncState;
                client.EndSend(res);

                OnDataSended(new DataSendedEventArgs());
            }else
                Console.WriteLine(string.Format("Socket say> Send data but not runing"));
        }
        #endregion

        #region Evenements
        public event EventHandler<ConnectedEventArgs> Connected;
        public event EventHandler<DisconnectedEventArgs> Disconnected;

        public event EventHandler<DataReceivedEventArgs> DataReceived;
        public event EventHandler<DataSendedEventArgs> DataSended;

        private void OnConnected(ConnectedEventArgs e)
        {
            if (Connected != null)
                Connected(this, e);
        }

        private void OnDisconnected(DisconnectedEventArgs e)
        {
            if (Disconnected != null)
                Disconnected(this, e);
        }

        private void OnDataReceived(DataReceivedEventArgs e)
        {
            if (DataReceived != null)
                DataReceived(this, e);
        }

        private void OnDataSended(DataSendedEventArgs e)
        {
            if (DataSended != null)
                DataSended(this, e);
        }
        #endregion

        #region Events Args
        public class ConnectedEventArgs : EventArgs
        {
        }

        public class DisconnectedEventArgs : EventArgs
        {
        }

        public class DataSendedEventArgs : EventArgs
        {
        }

        public class DataReceivedEventArgs : EventArgs
        {
            public Buffer Data { get; private set; }

            public DataReceivedEventArgs(Buffer data)
            {
                Data = data;
            }
        }
        #endregion
    }
Buffer (Classe pour décrypter et extraire les informations des packets)
C#:
class Buffer
    {
        public bool IsValid
        {
            get
            {
                return Header.HasValue && Length.HasValue &&
                       Length == Data.Length;
            }
        }

        public int? Header { get; private set; }

        public uint Count { get; private set; }

        public int? MessageId
        {
            get
            {
                if (!Header.HasValue)
                    return null;
                return Header >> 2;
            }
        }
        public string Name
        {
            get
            {
                if (!MessageId.HasValue)
                    return null;
                return Names.GetClasseName((int)MessageId);
            }
        }

        public int? LengthBytesCount
        {
            get
            {
                if (!Header.HasValue)
                    return null;
                return Header & 0x3;
            }
        }

        public int? Length { get; private set; }

        private byte[] m_data;

        public byte[] Data
        {
            get { return m_data; }
            private set { m_data = value; }
        }

        public byte[] FullPacket { get; set; }
        public bool Build(BigEndianReader reader, bool messageCounter)
        {
            this.FullPacket = reader.Data;

            if (IsValid)
                return true;

            if (reader.BytesAvailable >= 2 && !Header.HasValue)
            {
                Header = reader.ReadShort();
            }
            if (messageCounter)
                Count = reader.ReadUInt();

            if (LengthBytesCount.HasValue &&
                reader.BytesAvailable >= LengthBytesCount && !Length.HasValue)
            {
                Length = 0;
                for (int i = LengthBytesCount.Value - 1; i >= 0; i--)
                {
                    Length |= reader.ReadByte() << (i * 8);
                }
            }

            if (Data == null && Length.HasValue)
            {
                if (Length == 0)
                    Data = new byte[0];
                if (reader.BytesAvailable >= Length)
                {
                    Data = reader.ReadBytes(Length.Value);
                }
                else if (Length > reader.BytesAvailable)
                {
                    Data = reader.ReadBytes((int)reader.BytesAvailable);
                }
            }
            if (Data != null && Length.HasValue && Data.Length < Length)
            {
                int bytesToRead = 0;
                if (Data.Length + reader.BytesAvailable < Length)
                    bytesToRead = (int)reader.BytesAvailable;
                else if (Data.Length + reader.BytesAvailable >= Length)
                    bytesToRead = Length.Value - Data.Length;

                if (bytesToRead != 0)
                {
                    int oldLength = Data.Length;
                    Array.Resize(ref m_data, (int)(Data.Length + bytesToRead));
                    Array.Copy(reader.ReadBytes(bytesToRead), 0, Data, oldLength, bytesToRead);
                }
            }
            return IsValid;
        }

        public String Dump()
        {
            StringBuilder builder = new StringBuilder();
            foreach (byte elem in this.Data)
            {
                builder.AppendFormat("{0}{1}", (char)(elem / 16), (char)(elem % 16));
            }
            return (builder.ToString());
        }

    }
Classe principale
C#:
    class Sniffer
    {
        #region Properties
        private Server Serveur;

        public Client LocalClient;
        public Client RemoteClient;
        private string Address { get; set; }
        private int Port { get; set; }
        public uint GlobalInstanceId { get; set; }

        public List<Session> Sessions = new List<Session>();
        public Session MySession { get; set; }
        #endregion

        #region Constructeur
        public Sniffer()
        {
            Serveur = new Server();
            Serveur.Start(5555);
            Serveur.Listen();

            Serveur.ConnectionAccepted += Server_AcceptedConnection;

            GlobalInstanceId = 0;
        }
        #endregion

        #region Méthode Publique
        public void SendMessage(NetworkMessage message, uint globalId)
        {
            BigEndianWriter writer = new BigEndianWriter();
            message.Serialize(writer);

            message.Pack(writer, globalId);
            LocalClient.Send(writer.Data);
        }
        #endregion

        #region Méthode Privée
        private void Server_AcceptedConnection(object sender, Socket client)
        {
            LocalClient = new Client(client, true);
            RemoteClient = new Client();

            LocalClient.DataReceived += Local_DataReceived;
            RemoteClient.DataReceived += Remote_DataReceived;

            if(Address != null)
            {
                string Hostname = Address;
                IPAddress[] AdressList = Dns.GetHostAddresses(Hostname);

                RemoteClient.Start(IPAddress.Parse(AdressList[0].ToString()), Port);

                this.Address = null;
            }
            else
            {
                RemoteClient.Start(IPAddress.Parse("34.252.21.81"), 5555);
            }
        }

        private void Local_DataReceived(object sender, Client.DataReceivedEventArgs e)
        {
            GlobalInstanceId++;

            Console.WriteLine("Local say> Id: " +  "[" + e.Data.MessageId + "]" + "Full Length: [" + e.Data.FullPacket + "] DataLength: [" + e.Data.Data.Length + "]");
            
            RemoteClient.Send(e.Data, true);
        }

        private void Remote_DataReceived(object sender, Client.DataReceivedEventArgs e)
        {
            GlobalInstanceId++;

            Console.WriteLine("Remote say> Id: " + "[" + e.Data.MessageId + "]" + "Full Length: [" + e.Data.FullPacket.Length + "] DataLength: [" + e.Data.Data.Length + "]");

            if (e.Data.MessageId == 42)
            {
                BigEndianReader Reader = new BigEndianReader(e.Data.Data);
                SelectedServerDataMessage Selected = new SelectedServerDataMessage();

                Selected.Deserialize(Reader);

                Address = Selected.Address;
                Port = Selected.Ports[0];

                Selected.Address = "127.0.0.1";
                Selected.Ports.Add(5555);

                BigEndianWriter Writer = new BigEndianWriter();

                Selected.PackOld(Writer);

                LocalClient.Send(Writer.Data);
                LocalClient.Stop();

                RemoteClient.Stop();

                Console.WriteLine("Server say> Migration vers le serveur de jeu...");
            }
            else
            {
                LocalClient.Send(e.Data, false);

                if(e.Data.MessageId == 153)
                {
                    BigEndianReader Readerr = new BigEndianReader(e.Data.Data);
                    CharacterSelectedSuccessMessage Selected = new CharacterSelectedSuccessMessage();

                    Selected.Deserialize(Readerr);
                    Console.WriteLine("!!!!!!!!!!!! say> Perso sélectionné: " + Selected.Infos.Name);

                    if (Sessions.Count > 0)
                    {
                        MySession = new Session(Selected.Infos.Name, LocalClient, false);
                    }
                    else
                    {
                        MySession = new Session(Selected.Infos.Name, LocalClient, false);
                    }
                }
            }
        }
        #endregion
    }
 
Haut Bas