static X509Certificate2 GetCA(string basePath, string caName)
        {
            string path = Path.Join(basePath, caName);

            if (File.Exists(path))
            {
                return(new X509Certificate2(path));
            }


            var ca = TLSCertificate.CreateCA("PornhubApp CA", 2048, 3000);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                using X509Store store = new(StoreName.Root, StoreLocation.CurrentUser);

                store.Open(OpenFlags.ReadWrite);

                store.Add(new X509Certificate2(ca.Export(X509ContentType.Cert)));
            }


            File.WriteAllBytes(path, ca.Export(X509ContentType.Pfx));


            return(ca);
        }
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
            TaskScheduler.UnobservedTaskException        += TaskScheduler_UnobservedTaskException;
            //RuntimeInformation.IsOSPlatform



            string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets");

            byte[] vidoBuffer = File.ReadAllBytes(Path.Combine(basePath, "ad.mp4"));
            var    ca         = GetCA(basePath, "myCA.pfx");
            Info   info       = JsonSerializer.Deserialize <Info>(File.ReadAllText(Path.Combine(basePath, "info.json"), Encoding.UTF8), new JsonSerializerOptions {
                ReadCommentHandling = JsonCommentHandling.Skip
            });


            const string PORNHUB_DNS_HOST = "www.livehub.com";

            const string PORNHUB_HOST = "pornhub.com";

            const string IWARA_HOST = "iwara.tv";

            const string HENTAI_HOST = "e-hentai.org";

            const string AD_HOST = "adtng.com";

            const string APKMIRROR_HOST = "apkmirror.com";

            const string APKPURE_HOST = "apkpure.com";

            var pacListensEndPoint = IPEndPoint.Parse(info.PacServerListen);
            var listenEndPoint     = IPEndPoint.Parse(info.ProxyServerListen);
            var invalidEndpoint    = IPEndPoint.Parse(info.InvalidIPEndPoint);
            var pacWriteEndPoint   = IPEndPoint.Parse(info.PacProxyIPEndPoint);
            var adVido             = vidoBuffer;



            var mainCert      = TLSCertificate.CreateTlsCertificate(ca, PORNHUB_HOST, 2048, 2, PORNHUB_HOST, "*." + PORNHUB_HOST);
            var adCert        = TLSCertificate.CreateTlsCertificate(ca, AD_HOST, 2048, 2, AD_HOST, "*." + AD_HOST);
            var hentaiCert    = TLSCertificate.CreateTlsCertificate(ca, HENTAI_HOST, 2048, 2, HENTAI_HOST, "*." + HENTAI_HOST);
            var apkmirrorCert = TLSCertificate.CreateTlsCertificate(ca, APKMIRROR_HOST, 2048, 2, APKMIRROR_HOST, "*." + APKMIRROR_HOST);
            var apkpureCert   = TLSCertificate.CreateTlsCertificate(ca, APKPURE_HOST, 2048, 2, APKPURE_HOST, "*." + APKPURE_HOST);



            PacServer.Builder.Create(pacListensEndPoint)
            .Add((host) => host == "www.pornhub.com", ProxyMode.CreateHTTP(invalidEndpoint))
            .Add((host) => host == "hubt.pornhub.com", ProxyMode.CreateHTTP(invalidEndpoint))
            .Add((host) => host == "ajax.googleapis.com", ProxyMode.CreateHTTP(invalidEndpoint))
            .Add((host) => PacMethod.dnsDomainIs(host, PORNHUB_HOST), ProxyMode.CreateHTTP(pacWriteEndPoint))
            .Add((host) => PacMethod.dnsDomainIs(host, AD_HOST), ProxyMode.CreateHTTP(pacWriteEndPoint))
            .Add((host) => host == "i.iwara.tv", ProxyMode.CreateDIRECT())
            .Add((host) => PacMethod.dnsDomainIs(host, IWARA_HOST), ProxyMode.CreateHTTP(pacWriteEndPoint))
            .Add((host) => PacMethod.dnsDomainIs(host, HENTAI_HOST), ProxyMode.CreateHTTP(pacWriteEndPoint))
            .Add((host) => PacMethod.dnsDomainIs(host, APKMIRROR_HOST), ProxyMode.CreateHTTP(pacWriteEndPoint))
            .Add((host) => PacMethod.dnsDomainIs(host, APKPURE_HOST), ProxyMode.CreateHTTP(pacWriteEndPoint))
            .StartPACServer();


            SetAutoPac(pacListensEndPoint);

            PornhubProxyInfo pornhubInfo = new PornhubProxyInfo
            {
                MainPageStreamCreate = ConnectHelper.CreateLocalStream(new X509Certificate2(mainCert), SslProtocols.Tls12),

                ADPageStreamCreate = ConnectHelper.CreateLocalStream(new X509Certificate2(adCert), SslProtocols.Tls12),

                RemoteStreamCreate = ConnectHelper.CreateRemoteStream(PORNHUB_DNS_HOST, 443, PORNHUB_DNS_HOST, (a, b) => new MHttpStream(a, b), SslProtocols.Tls12),

                MaxContentSize = 1024 * 1024 * 5,

                ADVideoBytes = adVido,

                CheckingVideoHtml = PornhubHelper.CheckingVideoHtml,

                MaxRefreshRequestCount = 30,

                ReplaceResponseHtml = PornhubHelper.ReplaceResponseHtml
            };


            var pornhubAction = PornhubProxyServer.Start(pornhubInfo);


            TunnelProxyInfo iwaraSniInfo = new TunnelProxyInfo()
            {
                CreateLocalStream  = ConnectHelper.CreateDnsLocalStream(),
                CreateRemoteStream = ConnectHelper.CreateDnsRemoteStream(
                    443,
                    "104.26.12.12",
                    "104.20.201.232",
                    "104.24.48.227",
                    "104.22.27.126",
                    "104.24.53.193")
            };

            var iwaraAction = TunnelProxy.Create(iwaraSniInfo);



            TunnelProxyInfo hentaiInfo = new TunnelProxyInfo()
            {
                CreateLocalStream = ConnectHelper.CreateLocalStream(hentaiCert, SslProtocols.Tls12),

                CreateRemoteStream = ConnectHelper.CreateRemoteStream("46.101.100.115", 443, "104.20.135.21", (s, ssl) => (Stream)ssl, SslProtocols.Tls12)
            };

            var ehentaiAction = TunnelProxy.Create(hentaiInfo);



            TunnelProxyInfo apkmirrorInfo = new TunnelProxyInfo()
            {
                CreateLocalStream  = ConnectHelper.CreateLocalStream(apkmirrorCert, SslProtocols.Tls12),
                CreateRemoteStream = ConnectHelper.CreateRemoteStream("104.19.133.58", 443, "104.19.133.58", (s, ssl) => (Stream)ssl, SslProtocols.None)
            };

            var apkmirrorAction = TunnelProxy.Create(apkmirrorInfo);



            TunnelProxyInfo apkpureInfo = new TunnelProxyInfo()
            {
                //https://apkpure.com/
                //172.67.1.139
                CreateLocalStream  = ConnectHelper.CreateLocalStream(apkpureCert, SslProtocols.Tls12),
                CreateRemoteStream = ConnectHelper.CreateRemoteStream("172.67.1.139", 443, "172.67.1.139", (s, ssl) => (Stream)ssl, SslProtocols.None)
            };

            var apkpureAction = TunnelProxy.Create(apkpureInfo);


            var forw = ForwardTunnelRequest.Builder.Create()
                       .Add(IWARA_HOST, iwaraAction)
                       .Add(PORNHUB_HOST, pornhubAction)
                       .Add(AD_HOST, pornhubAction)
                       .Add(HENTAI_HOST, ehentaiAction)
                       .Add(APKMIRROR_HOST, apkmirrorAction)
                       .Add(APKPURE_HOST, apkpureAction)
                       .Get(listenEndPoint);

            forw.ListenTask.Wait();
        }