private static void ProcessICMPPing(ServerData sData, int pingTimeout, PingReply reply)
        {
            string prefix = String.Format("[P {0}][IP:p {1}:{2}]", sData.Project, sData.IP, sData.port);

            Console.WriteLine(String.Format(
                                  "{0} Reply status: {1}",
                                  prefix,
                                  reply.Status.ToString()
                                  ));

            if (reply.Status == IPStatus.TimedOut)
            {
                sData.pingICMP = pingTimeout;
            }
            else
            {
                sData.pingICMP = reply.RoundtripTime;
            }

            if (sData.pingICMP < ServerList.SHOW_THRESHOLD)
            {
                ServerList.servers.Add(sData);
                ServerList.ShakeData();
            }
            else
            {
                Console.WriteLine(String.Format(
                                      "[P {0}][IP:p {1}:{2}] Server is out of reach. Ping: {3}",
                                      sData.Project,
                                      sData.IP,
                                      sData.port,
                                      sData.pingICMP
                                      ));
            }
        }
Esempio n. 2
0
        static bool Prefix()
        {
            FryLabsServerList.UI.Instance.IsModEnabled = Main.enabled;
            FryLabsServerList.UI.Instance.Opened       = true;

            if (ServerList.servers.Count == 0)
            {
                ServerList.Search();
            }

            // Don't run original function if our browser is enabled
            return(!Main.enabled);
        }
        private static async void ServersParse()
        {
            ServerList.cts?.Dispose();
            ServerList.cts = new CancellationTokenSource();

            // Prepare ping
            string pingData = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

            byte[]      pingBuffer  = Encoding.ASCII.GetBytes(pingData);
            PingOptions pingOptions = new PingOptions(64, true);

            var strings = ServerList._serversRaw.Split(new string[] { "<br>" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var data in strings)
            {
                var parts = data.Split(';');

                var sData = new ServerData();
                sData.counter = ServerList.counter;
                ServerList.counter++;

                sData.IP   = parts[0];
                sData.port = int.Parse(parts[1]);

                var fav = false;
                // TODO
                // try
                // {
                //   if (this._window.favourites.TryGetValue(sData.Address, out ServerData cache))
                //   {
                //     fav = cache.IsFavourite;
                //   };
                // }
                // catch (NullReferenceException e) { }
                sData.IsFavourite = fav;

                sData.serverInfo    = ServerInfo.Parse(parts[2]);
                sData.serverPlayers = ServerPlayers.Parse(parts[3]);

                // ServerList.PingICMPAsync(sData, ServerList.PING_THRESHOLD, pingBuffer, pingOptions);
                ServerList.PingUnity(sData, ServerList.PING_THRESHOLD);

                await Task.Delay(0);
            }
        }
        private static async void PingUnity(ServerData sData, int pingTimeout)
        {
            string IP = sData.IP;

            try
            {
                IPAddress.Parse(IP);
            }
            catch (FormatException)
            {
                IPHostEntry hostInfo = Dns.GetHostEntry(sData.IP);
                IP = hostInfo.AddressList.First().ToString();
            }

            Task <int> pingTask = ServerList.PingUnityAsync(IP);

            ServerList.unityPingTasks.Add(pingTask);

            try
            {
                sData.pingICMP = await pingTask;
            }
            catch (OperationCanceledException)
            {
                sData.pingICMP = pingTimeout;
            }

            if (sData.pingICMP < ServerList.SHOW_THRESHOLD)
            {
                ServerList.servers.Add(sData);
                ServerList.ShakeData();
            }
            else
            {
                Console.WriteLine(String.Format(
                                      "[P {0}][IP:p {1}:{2}] Server is out of reach. Ping: {3}",
                                      sData.Project,
                                      sData.IP,
                                      sData.port,
                                      sData.pingICMP
                                      ));
            }
        }
        public static void ShakeData()
        {
            ServerList.servers.Sort((a, b) => {
                var diffPing = (int)(a.Ping - b.Ping);
                if (diffPing != 0)
                {
                    return(diffPing);
                }

                if (a.serverInfo.discord == "" && b.serverInfo.discord != "")
                {
                    return(1);
                }
                if (a.serverInfo.discord != "" && b.serverInfo.discord == "")
                {
                    return(-1);
                }

                var diffProject = string.Compare(a.serverInfo.discord, b.serverInfo.discord);
                if (diffProject != 0)
                {
                    // We are kinda respecting original sort order
                    return(a.counter - b.counter);
                }

                var diffName = string.Compare(a.Info, b.Info);
                if (diffName != 0)
                {
                    return(diffName);
                }

                return(a.serverPlayers.current - b.serverPlayers.current);
            });

            if (ServerList.servers.Count > 100)
            {
                ServerList.PingStop();
                ServerList.servers.RemoveRange(100, ServerList.servers.Count - 100);
            }
        }
        public static void Search()
        {
            UI.status = "Requesting server data...";

            ServerList.servers.Clear();
            ServerList.pings.Clear();
            ServerList.counter = 0;

            using (var client = new WebClient())
            {
                client.DownloadStringCompleted += (s, e) => {
                    if (e.Error != null)
                    {
                        UI.status = "Requesting server data... Error!";
                        return;
                    }

                    UI.status = "Requesting server data... Complete!";
                    ServerList._serversRaw = e.Result;
                    ServerList.ServersParse();
                };
                client.DownloadStringAsync(ServerList.endpointLobby);
            }
        }
        // FIXME this is blocked by some providers as "ICMP flood"
        // FIXME make selector between this and Unity
        private static void PingICMPAsync(ServerData ret, int pingTimeout, byte[] pingBuffer, PingOptions pingOptions)
        {
            using (var ping = new Ping())
            {
                ServerList.pings.Add(ping);

                string prefix = String.Format("[P {0}][IP:p {1}:{2}]", ret.Project, ret.IP, ret.port);

                ping.PingCompleted += (s, e) => {
                    if (e.Cancelled)
                    {
                        Console.WriteLine(String.Format(
                                              "{0} Ping was cancelled.",
                                              prefix
                                              ));

                        ((AutoResetEvent)e.UserState).Set();
                        return;
                    }

                    if (e.Error != null)
                    {
                        Console.WriteLine(String.Format(
                                              "{0} Error! {1}",
                                              prefix,
                                              e.Error.ToString()
                                              ));

                        ((AutoResetEvent)e.UserState).Set();
                        return;
                    }

                    ServerList.ProcessICMPPing(ret, pingTimeout, e.Reply);
                    ((AutoResetEvent)e.UserState).Set();
                };

                AutoResetEvent pingWaiter = new AutoResetEvent(false);
                try
                {
                    ping.SendAsync(IPAddress.Parse(ret.IP), pingTimeout, pingBuffer, pingOptions, pingWaiter);
                    return;
                }
                catch (FormatException) {
                    // server IP was probably server NS
                    // we will retry call directly
                }
                catch (SocketException e)
                {
                    Console.WriteLine(e.ToString());
                    return;
                }

                try
                {
                    ping.SendAsync(ret.IP, pingTimeout, pingBuffer, pingOptions, pingWaiter);
                    return;
                }
                catch (SocketException e)
                {
                    Console.WriteLine(e.ToString());
                    return;
                }
            }
        }
        // Called by window in loop?
        private void WindowFunction(int windowId)
        {
            if (Input.GetAxisRaw("Mouse ScrollWheel") != 0)
            {
                UI.scrollPos.y += Input.GetAxisRaw("Mouse ScrollWheel");
            }

            if (!UI.isButtonStyleInitialized)
            {
                UI.button                   = new GUIStyle(GUI.skin.button);
                UI.button.alignment         = TextAnchor.MiddleCenter;
                UI.button.margin            = new RectOffset(0, 0, 0, 0);
                UI.isButtonStyleInitialized = true;
            }

            GUILayout.Label(
                String.Format(
                    "{0} v{1}",
                    FryLabsServerList.Main.mod.Info.DisplayName,
                    FryLabsServerList.Main.mod.Info.Version
                    ),
                UnityModManager.UI.h1
                );
            GUILayout.Space(5);

            UI.scrollPos = GUILayout.BeginScrollView(UI.scrollPos, GUILayout.MinWidth(mWindowSize.x), GUILayout.MaxWidth(mWindowSize.x));
            GUILayout.BeginVertical();

            foreach (ServerData sData in ServerList.servers)
            {
                GUILayout.Space(3);

                GUILayout.BeginHorizontal(GUILayout.MinWidth(mWindowSize.x - 15), GUILayout.MaxWidth(mWindowSize.x - 15));

                GUILayout.Label(sData.Project, UI.textLeft, GUILayout.Width(150), GUILayout.ExpandWidth(false));
                GUILayout.Label(sData.Info, UI.textInfo, GUILayout.MaxWidth(mWindowSize.x - 440));
                GUILayout.Label(sData.Players, UI.textCenter, GUILayout.Width(50), GUILayout.ExpandWidth(false));
                GUILayout.Label(sData.Ping.ToString(), UI.textCenter, GUILayout.Width(25), GUILayout.ExpandWidth(false));

                if (GUILayout.Button("Discord", UI.button, GUILayout.ExpandWidth(false)))
                {
                    ServerList.Discord(sData);
                }

                if (GUILayout.Button("Rules", UI.button, GUILayout.ExpandWidth(false)))
                {
                    ToggleWindow(false);
                    global::ServerInfo.ShowInfo(sData.serverInfo.pastebin);
                }

                if (GUILayout.Button("Connect", UI.button, GUILayout.ExpandWidth(false)))
                {
                    ToggleWindow(false);
                    ServerList.Connect(sData);
                }

                GUILayout.EndHorizontal();

                GUILayout.Space(3);
                GUILayout.Label(GUIContent.none, UI.separator, GUILayout.ExpandWidth(true), GUILayout.Height(1f));
            }

            GUILayout.EndVertical();
            GUILayout.EndScrollView();

            GUILayout.FlexibleSpace();
            GUILayout.Space(5);

            GUILayout.BeginHorizontal();
            GUILayout.Label(UI.status);
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Close", UnityModManager.UI.button, GUILayout.ExpandWidth(false)))
            {
                ToggleWindow(false);
            }
            if (GUILayout.Button("Refresh", UnityModManager.UI.button, GUILayout.ExpandWidth(false)))
            {
                ServerList.Search();
            }
            GUILayout.EndHorizontal();
        }