Example #1
0
        private void PingTunnels(object _tunnels)
        {
            List <CnCNetTunnel> Tunnels = (List <CnCNetTunnel>)_tunnels;

            for (int tnlId = 0; tnlId < Tunnels.Count; tnlId++)
            {
                CnCNetTunnel tunnel = Tunnels[tnlId];
                if (!tunnel.Official)
                {
                    int  pingInMs = -1;
                    Ping p        = new Ping();
                    try
                    {
                        PingReply reply = p.Send(IPAddress.Parse(tunnel.Address), 500);
                        if (reply.Status == IPStatus.Success)
                        {
                            if (reply.RoundtripTime > 0)
                            {
                                pingInMs = Convert.ToInt32(reply.RoundtripTime);
                            }
                        }
                    }
                    catch
                    {
                    }

                    if (pingInMs > -1)
                    {
                        tunnel.PingInMs = pingInMs;
                    }

                    DoTunnelPinged(tnlId, pingInMs);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Parses a formatted string that contains the tunnel server's
        /// information into a CnCNetTunnel instance.
        /// </summary>
        /// <param name="str">The string that contains the tunnel server's information.</param>
        /// <returns>A CnCNetTunnel instance parsed from the given string.</returns>
        public static CnCNetTunnel Parse(string str)
        {
            // For the format, check http://cncnet.org/master-list

            try
            {
                var      tunnel = new CnCNetTunnel();
                string[] parts  = str.Split(';');

                string   address         = parts[0];
                string[] detailedAddress = address.Split(new char[] { ':' });

                tunnel.Address          = detailedAddress[0];
                tunnel.Port             = int.Parse(detailedAddress[1]);
                tunnel.Country          = parts[1];
                tunnel.CountryCode      = parts[2];
                tunnel.Name             = parts[3];
                tunnel.RequiresPassword = parts[4] != "0";
                tunnel.Clients          = int.Parse(parts[5]);
                tunnel.MaxClients       = int.Parse(parts[6]);
                int status = int.Parse(parts[7]);
                tunnel.Official = status == 2;
                if (!tunnel.Official)
                {
                    tunnel.Recommended = status == 1;
                }

                CultureInfo cultureInfo = CultureInfo.InvariantCulture;

                tunnel.Latitude  = double.Parse(parts[8], cultureInfo);
                tunnel.Longitude = double.Parse(parts[9], cultureInfo);
                tunnel.Version   = int.Parse(parts[10]);
                tunnel.Distance  = double.Parse(parts[11], cultureInfo);

                return(tunnel);
            }
            catch (Exception ex)
            {
                if (ex is FormatException || ex is OverflowException || ex is IndexOutOfRangeException)
                {
                    Logger.Log("Parsing tunnel information failed: " + ex.Message + Environment.NewLine + "Parsed string: " + str);
                    return(null);
                }

                throw ex;
            }
        }
        private void HandleRefreshedTunnels(List <CnCNetTunnel> tunnels)
        {
            if (tunnels.Count > 0)
            {
                Tunnels = tunnels;
            }

            TunnelsRefreshed?.Invoke(this, EventArgs.Empty);

            Task[] pingTasks = new Task[Tunnels.Count];

            for (int i = 0; i < Tunnels.Count; i++)
            {
                if (UserINISettings.Instance.PingUnofficialCnCNetTunnels || Tunnels[i].Official || Tunnels[i].Recommended)
                {
                    pingTasks[i] = PingListTunnelAsync(i);
                }
            }

            if (CurrentTunnel != null)
            {
                var updatedTunnel = Tunnels.Find(t => t.Address == CurrentTunnel.Address && t.Port == CurrentTunnel.Port);
                if (updatedTunnel != null)
                {
                    // don't re-ping if the tunnel still exists in list, just update the tunnel instance and
                    // fire the event handler (the tunnel was already pinged when traversing the tunnel list)
                    CurrentTunnel = updatedTunnel;
                    DoCurrentTunnelPinged();
                }
                else
                {
                    // tunnel is not in the list anymore so it's not updated with a list instance and pinged
                    PingCurrentTunnelAsync();
                }
            }
        }
Example #4
0
        /// <summary>
        /// Downloads and parses the list of CnCNet tunnels.
        /// </summary>
        /// <returns>A list of tunnel servers.</returns>
        private List <CnCNetTunnel> RefreshTunnels()
        {
            string tunnelCacheFile = ProgramConstants.GamePath + "Client\\tunnel_cache";

            List <CnCNetTunnel> returnValue = new List <CnCNetTunnel>();

            WebClient client = new WebClient();

            byte[] data;

            Logger.Log("Fetching tunnel server info.");

            try
            {
                data = client.DownloadData(MainClientConstants.CNCNET_TUNNEL_LIST_URL);
            }
            catch (Exception ex)
            {
                Logger.Log("Error when downloading tunnel server info: " + ex.Message);
                Logger.Log("Retrying.");
                try
                {
                    data = client.DownloadData(MainClientConstants.CNCNET_TUNNEL_LIST_URL);
                }
                catch
                {
                    if (!File.Exists(tunnelCacheFile))
                    {
                        Logger.Log("Tunnel cache file doesn't exist!");
                        return(returnValue);
                    }
                    else
                    {
                        Logger.Log("Fetching tunnel server list failed. Using cached tunnel data.");
                        data = File.ReadAllBytes(tunnelCacheFile);
                    }
                }
            }

            string convertedData = Encoding.Default.GetString(data);

            string[] serverList = convertedData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string serverInfo in serverList)
            {
                try
                {
                    CnCNetTunnel tunnel = CnCNetTunnel.Parse(serverInfo);

                    if (tunnel == null)
                    {
                        continue;
                    }

                    if (tunnel.RequiresPassword)
                    {
                        continue;
                    }

                    if (tunnel.Version != SUPPORTED_TUNNEL_VERSION)
                    {
                        continue;
                    }

                    if (tunnel.Official || tunnel.Recommended)
                    {
                        Ping p = new Ping();
                        try
                        {
                            PingReply reply = p.Send(IPAddress.Parse(tunnel.Address), 500);
                            if (reply.Status == IPStatus.Success)
                            {
                                if (reply.RoundtripTime > 0)
                                {
                                    tunnel.PingInMs = Convert.ToInt32(reply.RoundtripTime);
                                }
                            }
                        }
                        catch
                        {
                        }
                    }

                    returnValue.Add(tunnel);
                }
                catch
                {
                }
            }

            if (returnValue.Count > 0)
            {
                try
                {
                    if (File.Exists(tunnelCacheFile))
                    {
                        File.Delete(tunnelCacheFile);
                    }
                    if (!Directory.Exists(ProgramConstants.GamePath + "Client"))
                    {
                        Directory.CreateDirectory(ProgramConstants.GamePath + "Client");
                    }
                    File.WriteAllBytes(tunnelCacheFile, data);
                }
                catch (Exception ex)
                {
                    Logger.Log("Refreshing tunnel cache file failed! Returned error: " + ex.Message);
                }
            }

            return(returnValue);
        }
Example #5
0
        /// <summary>
        /// Downloads and parses the list of CnCNet tunnels.
        /// </summary>
        /// <returns>A list of tunnel servers.</returns>
        private List <CnCNetTunnel> RefreshTunnels()
        {
            string tunnelCacheFile = ProgramConstants.GamePath + "Client\\tunnel_cache";

            List <CnCNetTunnel> returnValue = new List <CnCNetTunnel>();

            WebClient client = new WebClient();

            byte[] data;

            Logger.Log("Fetching tunnel server info.");

            try
            {
                data = client.DownloadData("http://cncnet.org/master-list");
            }
            catch (Exception ex)
            {
                Logger.Log("Error when downloading tunnel server info: " + ex.Message);
                Logger.Log("Retrying.");
                try
                {
                    data = client.DownloadData("http://cncnet.org/master-list");
                }
                catch
                {
                    if (!File.Exists(tunnelCacheFile))
                    {
                        Logger.Log("Tunnel cache file doesn't exist!");
                        return(returnValue);
                    }
                    else
                    {
                        Logger.Log("Fetching tunnel server list failed. Using cached tunnel data.");
                        data = File.ReadAllBytes(tunnelCacheFile);
                    }
                }
            }

            string convertedData = Encoding.Default.GetString(data);

            string[] serverList = convertedData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string serverinfo in serverList)
            {
                string[] serverInfo = serverinfo.Split(new char[] { ';' });

                CnCNetTunnel tunnel = new CnCNetTunnel();

                try
                {
                    string   address         = serverInfo[0];
                    string[] detailedAddress = address.Split(new char[] { ':' });
                    tunnel.Address = detailedAddress[0];
                    tunnel.Port    = Convert.ToInt32(detailedAddress[1]);

                    tunnel.Country          = serverInfo[1];
                    tunnel.CountryCode      = serverInfo[2];
                    tunnel.Name             = serverInfo[3];
                    tunnel.RequiresPassword = Conversions.BooleanFromString(serverInfo[4], true);
                    tunnel.Clients          = Convert.ToInt32(serverInfo[5]);
                    tunnel.MaxClients       = Convert.ToInt32(serverInfo[6]);
                    tunnel.Official         = (Convert.ToInt32(serverInfo[7]) == 2);
                    if (!tunnel.Official)
                    {
                        tunnel.Recommended = (Convert.ToInt32(serverInfo[7]) == 1);
                    }

                    CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-US");

                    tunnel.Latitude  = Convert.ToDouble(serverInfo[8], cultureInfo);
                    tunnel.Longitude = Convert.ToDouble(serverInfo[9], cultureInfo);
                    tunnel.Version   = Convert.ToInt32(serverInfo[10]);
                    tunnel.Distance  = Convert.ToDouble(serverInfo[11], cultureInfo);
                    tunnel.PingInMs  = -1;

                    if (tunnel.RequiresPassword)
                    {
                        continue;
                    }

                    if (tunnel.Version != 2)
                    {
                        continue;
                    }

                    if (tunnel.Official || tunnel.Recommended)
                    {
                        Ping p = new Ping();
                        try
                        {
                            PingReply reply = p.Send(IPAddress.Parse(detailedAddress[0]), 500);
                            if (reply.Status == IPStatus.Success)
                            {
                                if (reply.RoundtripTime > 0)
                                {
                                    tunnel.PingInMs = Convert.ToInt32(reply.RoundtripTime);
                                }
                            }
                        }
                        catch
                        {
                        }
                    }

                    returnValue.Add(tunnel);
                }
                catch
                {
                }
            }

            if (returnValue.Count > 0)
            {
                try
                {
                    if (File.Exists(tunnelCacheFile))
                    {
                        File.Delete(tunnelCacheFile);
                    }
                    if (!Directory.Exists(ProgramConstants.GamePath + "Client"))
                    {
                        Directory.CreateDirectory(ProgramConstants.GamePath + "Client");
                    }
                    File.WriteAllBytes(tunnelCacheFile, data);
                }
                catch (Exception ex)
                {
                    Logger.Log("Refreshing tunnel cache file failed! Returned error: " + ex.Message);
                }
            }

            return(returnValue);
        }