// Decompiled with JetBrains decompiler
// Type: Meebey.SmartIrc4net.IrcFeatures
// 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.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Threading;

namespace Meebey.SmartIrc4net
{
  public class IrcFeatures : IrcClient
  {
    private IPAddress _ExternalIpAdress;
    private List<DccConnection> _DccConnections = new List<DccConnection>();
    private Dictionary<string, CtcpDelegate> _CtcpDelegates = new Dictionary<string, CtcpDelegate>((IEqualityComparer<string>) StringComparer.CurrentCultureIgnoreCase);
    private string _CtcpUserInfo;
    private string _CtcpUrl;
    private string _CtcpSource;
    internal DccSpeed Speed = DccSpeed.RfcSendAhead;

    public IPAddress ExternalIpAdress
    {
      get => this._ExternalIpAdress;
      set => this._ExternalIpAdress = value;
    }

    public ReadOnlyCollection<DccConnection> DccConnections => new ReadOnlyCollection<DccConnection>((IList<DccConnection>) this._DccConnections);

    public Dictionary<string, CtcpDelegate> CtcpDelegates => this._CtcpDelegates;

    public string CtcpUserInfo
    {
      get => this._CtcpUserInfo;
      set => this._CtcpUserInfo = value;
    }

    public string CtcpUrl
    {
      get => this._CtcpUrl;
      set => this._CtcpUrl = value;
    }

    public string CtcpSource
    {
      get => this._CtcpSource;
      set => this._CtcpSource = value;
    }

    public event DccConnectionHandler OnDccChatRequestEvent;

    public void DccChatRequestEvent(DccEventArgs e)
    {
      if (this.OnDccChatRequestEvent == null)
        return;
      this.OnDccChatRequestEvent((object) this, e);
    }

    public event DccSendRequestHandler OnDccSendRequestEvent;

    public void DccSendRequestEvent(DccSendRequestEventArgs e)
    {
      if (this.OnDccSendRequestEvent == null)
        return;
      this.OnDccSendRequestEvent((object) this, e);
    }

    public event DccConnectionHandler OnDccChatStartEvent;

    public void DccChatStartEvent(DccEventArgs e)
    {
      if (this.OnDccChatStartEvent == null)
        return;
      this.OnDccChatStartEvent((object) this, e);
    }

    public event DccConnectionHandler OnDccSendStartEvent;

    public void DccSendStartEvent(DccEventArgs e)
    {
      if (this.OnDccSendStartEvent == null)
        return;
      this.OnDccSendStartEvent((object) this, e);
    }

    public event DccChatLineHandler OnDccChatReceiveLineEvent;

    public void DccChatReceiveLineEvent(DccChatEventArgs e)
    {
      if (this.OnDccChatReceiveLineEvent == null)
        return;
      this.OnDccChatReceiveLineEvent((object) this, e);
    }

    public event DccSendPacketHandler OnDccSendReceiveBlockEvent;

    public void DccSendReceiveBlockEvent(DccSendEventArgs e)
    {
      if (this.OnDccSendReceiveBlockEvent == null)
        return;
      this.OnDccSendReceiveBlockEvent((object) this, e);
    }

    public event DccChatLineHandler OnDccChatSentLineEvent;

    public void DccChatSentLineEvent(DccChatEventArgs e)
    {
      if (this.OnDccChatSentLineEvent == null)
        return;
      this.OnDccChatSentLineEvent((object) this, e);
    }

    public event DccSendPacketHandler OnDccSendSentBlockEvent;

    internal void DccSendSentBlockEvent(DccSendEventArgs e)
    {
      if (this.OnDccSendSentBlockEvent == null)
        return;
      this.OnDccSendSentBlockEvent((object) this, e);
    }

    public event DccConnectionHandler OnDccChatStopEvent;

    public void DccChatStopEvent(DccEventArgs e)
    {
      if (this.OnDccChatStopEvent == null)
        return;
      this.OnDccChatStopEvent((object) this, e);
    }

    public event DccConnectionHandler OnDccSendStopEvent;

    public void DccSendStopEvent(DccEventArgs e)
    {
      if (this.OnDccSendStopEvent == null)
        return;
      this.OnDccSendStopEvent((object) this, e);
    }

    public IrcFeatures()
    {
      this.OnCtcpRequest += new CtcpEventHandler(this.CtcpRequestsHandler);
      this._CtcpDelegates.Add("version", new CtcpDelegate(this.CtcpVersionDelegate));
      this._CtcpDelegates.Add("clientinfo", new CtcpDelegate(this.CtcpClientInfoDelegate));
      this._CtcpDelegates.Add("time", new CtcpDelegate(this.CtcpTimeDelegate));
      this._CtcpDelegates.Add("userinfo", new CtcpDelegate(this.CtcpUserInfoDelegate));
      this._CtcpDelegates.Add("url", new CtcpDelegate(this.CtcpUrlDelegate));
      this._CtcpDelegates.Add("source", new CtcpDelegate(this.CtcpSourceDelegate));
      this._CtcpDelegates.Add("finger", new CtcpDelegate(this.CtcpFingerDelegate));
      this._CtcpDelegates.Add("dcc", new CtcpDelegate(this.CtcpDccDelegate));
      this._CtcpDelegates.Add("ping", new CtcpDelegate(this.CtcpPingDelegate));
    }

    public void InitDccChat(string user) => this.InitDccChat(user, false);

    public void InitDccChat(string user, bool passive) => this.InitDccChat(user, passive, Priority.Medium);

    public void InitDccChat(string user, bool passive, Priority priority)
    {
      DccChat dccChat = new DccChat(this, user, this._ExternalIpAdress, passive, priority);
      this._DccConnections.Add((DccConnection) dccChat);
      ThreadPool.QueueUserWorkItem(new WaitCallback(((DccConnection) dccChat).InitWork));
      this.RemoveInvalidDccConnections();
    }

    public void SendFile(string user, string filepath)
    {
      FileInfo fileInfo = new FileInfo(filepath);
      if (!fileInfo.Exists)
        return;
      this.SendFile(user, (Stream) new FileStream(filepath, FileMode.Open), fileInfo.Name, fileInfo.Length, DccSpeed.RfcSendAhead, false, Priority.Medium);
    }

    public void SendFile(string user, string filepath, bool passive)
    {
      FileInfo fileInfo = new FileInfo(filepath);
      if (!fileInfo.Exists)
        return;
      this.SendFile(user, (Stream) new FileStream(filepath, FileMode.Open), fileInfo.Name, fileInfo.Length, DccSpeed.RfcSendAhead, passive, Priority.Medium);
    }

    public void SendFile(string user, Stream file, string filename, long filesize) => this.SendFile(user, file, filename, filesize, DccSpeed.RfcSendAhead, false);

    public void SendFile(
      string user,
      Stream file,
      string filename,
      long filesize,
      DccSpeed speed,
      bool passive)
    {
      this.SendFile(user, file, filename, filesize, speed, passive, Priority.Medium);
    }

    public void SendFile(
      string user,
      Stream file,
      string filename,
      long filesize,
      DccSpeed speed,
      bool passive,
      Priority priority)
    {
      DccSend dccSend = new DccSend(this, user, this._ExternalIpAdress, file, filename, filesize, speed, passive, priority);
      this._DccConnections.Add((DccConnection) dccSend);
      ThreadPool.QueueUserWorkItem(new WaitCallback(((DccConnection) dccSend).InitWork));
      this.RemoveInvalidDccConnections();
    }

    private void CtcpRequestsHandler(object sender, CtcpEventArgs e)
    {
      if (this._CtcpDelegates.ContainsKey(e.CtcpCommand))
        this._CtcpDelegates[e.CtcpCommand](e);
      this.RemoveInvalidDccConnections();
    }

    private void CtcpVersionDelegate(CtcpEventArgs e) => this.SendMessage(SendType.CtcpReply, e.Data.Nick, "VERSION " + (this.CtcpVersion == null ? this.VersionString : this.CtcpVersion));

    private void CtcpClientInfoDelegate(CtcpEventArgs e)
    {
      string message = "CLIENTINFO";
      foreach (KeyValuePair<string, CtcpDelegate> ctcpDelegate in this._CtcpDelegates)
        message = message + " " + ctcpDelegate.Key.ToUpper();
      this.SendMessage(SendType.CtcpReply, e.Data.Nick, message);
    }

    private void CtcpPingDelegate(CtcpEventArgs e)
    {
      if (e.Data.Message.Length > 7)
        this.SendMessage(SendType.CtcpReply, e.Data.Nick, "PING " + e.Data.Message.Substring(6, e.Data.Message.Length - 7));
      else
        this.SendMessage(SendType.CtcpReply, e.Data.Nick, "PING");
    }

    private void CtcpRfcPingDelegate(CtcpEventArgs e)
    {
      if (e.Data.Message.Length > 7)
        this.SendMessage(SendType.CtcpReply, e.Data.Nick, "PONG " + e.Data.Message.Substring(6, e.Data.Message.Length - 7));
      else
        this.SendMessage(SendType.CtcpReply, e.Data.Nick, "PONG");
    }

    private void CtcpTimeDelegate(CtcpEventArgs e) => this.SendMessage(SendType.CtcpReply, e.Data.Nick, "TIME " + DateTime.Now.ToString("r"));

    private void CtcpUserInfoDelegate(CtcpEventArgs e) => this.SendMessage(SendType.CtcpReply, e.Data.Nick, "USERINFO " + (this.CtcpUserInfo == null ? "No user info given." : this.CtcpUserInfo));

    private void CtcpUrlDelegate(CtcpEventArgs e) => this.SendMessage(SendType.CtcpReply, e.Data.Nick, "URL " + (this.CtcpUrl == null ? "http://www.google.com" : this.CtcpUrl));

    private void CtcpSourceDelegate(CtcpEventArgs e) => this.SendMessage(SendType.CtcpReply, e.Data.Nick, "SOURCE " + (this.CtcpSource == null ? "http://smartirc4net.meebey.net" : this.CtcpSource));

    private void CtcpFingerDelegate(CtcpEventArgs e) => this.SendMessage(SendType.CtcpReply, e.Data.Nick, "FINGER Don't touch little Helga there! ");

    private void CtcpDccDelegate(CtcpEventArgs e)
    {
      if (e.Data.MessageArray.Length < 2)
      {
        this.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC missing parameters");
      }
      else
      {
        switch (e.Data.MessageArray[1])
        {
          case "CHAT":
            DccChat dccChat = new DccChat(this, this._ExternalIpAdress, e);
            this._DccConnections.Add((DccConnection) dccChat);
            ThreadPool.QueueUserWorkItem(new WaitCallback(((DccConnection) dccChat).InitWork));
            break;
          case "SEND":
            if (e.Data.MessageArray.Length > 6 && this.FilterMarker(e.Data.MessageArray[6]) != "T")
            {
              long result = -1;
              long.TryParse(this.FilterMarker(e.Data.MessageArray[6]), out result);
              foreach (DccConnection dccConnection in this._DccConnections)
              {
                if (dccConnection.isSession(result))
                {
                  ((DccSend) dccConnection).SetRemote(e);
                  ((DccSend) dccConnection).AcceptRequest((Stream) null, 0L);
                  return;
                }
              }
              this.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG Invalid passive DCC");
              break;
            }
            DccSend dccSend = new DccSend(this, this._ExternalIpAdress, e);
            this._DccConnections.Add((DccConnection) dccSend);
            ThreadPool.QueueUserWorkItem(new WaitCallback(((DccConnection) dccSend).InitWork));
            break;
          case "RESUME":
            foreach (DccConnection dccConnection in this._DccConnections)
            {
              if (dccConnection is DccSend && ((DccSend) dccConnection).TryResume(e))
                return;
            }
            this.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG Invalid DCC RESUME");
            break;
          case "ACCEPT":
            foreach (DccConnection dccConnection in this._DccConnections)
            {
              if (dccConnection is DccSend && ((DccSend) dccConnection).TryAccept(e))
                return;
            }
            this.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG Invalid DCC ACCEPT");
            break;
          case "XMIT":
            this.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC XMIT not implemented");
            break;
          default:
            this.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC " + e.CtcpParameter + " unavailable");
            break;
        }
      }
    }

    private void RemoveInvalidDccConnections()
    {
      List<DccConnection> dccConnectionList = new List<DccConnection>();
      foreach (DccConnection dccConnection in this._DccConnections)
      {
        if (!dccConnection.Valid && !dccConnection.Connected)
          dccConnectionList.Add(dccConnection);
      }
      foreach (DccConnection dccConnection in dccConnectionList)
        this._DccConnections.Remove(dccConnection);
    }

    private string FilterMarker(string msg)
    {
      string str = "";
      foreach (char ch in msg)
      {
        if (ch != '\u0001')
          str += (string) (object) ch;
      }
      return str;
    }
  }
}
