コード例 #1
0
        /// <summary>
        /// Template method for common code needed in UpdateServerInfo, UpdatePlayers and UpdateRules
        /// </summary>
        private bool ExecuteUpdate(UpdateRequest request, ServerRow row, Server server, Func <Action <int>, bool> updater)
        {
            if (request.IsCancelled)
            {
                return(false);
            }

            try
            {
                row.Status = "updating " + row.Retries;
                request.SetDataModified();
                bool ok = updater(retry =>
                {
                    if (request.IsCancelled)
                    {
                        throw new OperationCanceledException();
                    }
                    if (row.Retries == 0)
                    {
                        Interlocked.Increment(ref request.TasksWithRetries);
                    }
                    row.Status = "updating " + (++row.Retries + 1);
                    request.SetDataModified();
                });
                if (ok)
                {
                    return(true);
                }
                Interlocked.Increment(ref request.TasksWithTimeout);
            }
            catch
            {
            }
            return(false);
        }
コード例 #2
0
        /// <summary>
        /// Start the game if necessary and then connect to the given game server.
        /// </summary>
        public virtual bool Connect(ServerRow server, string password, bool spectate)
        {
            this.ActivateGameWindow(this.FindGameWindow());
            var proc = Process.Start("steam://connect/" + server.EndPoint + (string.IsNullOrEmpty(password) ? "" : "/" + password));

            return(proc != null);
        }
コード例 #3
0
ファイル: Toxikk.cs プロジェクト: donkz/SteamServerBrowser
        public override bool Connect(ServerRow server, string password, bool spectate)
        {
            // servers with skill restrictions neither allow connections with "steam://connect" nor with an "open ip:port" console command
              if ((string) this.GetServerCellValue(server, "_skillclass") != "1-12")
              {
            var res = XtraMessageBox.Show("This server has a skill restriction.\nOnly the in-game browser can connect to such servers.\nLaunch TOXIKK anyway?",
              "Toxikk Server", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
            if (res == DialogResult.No)
              return false;
            if (FindToxikkWindow() == IntPtr.Zero)
              StartToxikk();
            return true;
              }

              if (consoleKey == Keys.None)
              {
            using (var dlg = new KeyBindForm("Please press your Toxikk console key..."))
            {
              if (dlg.ShowDialog(Application.OpenForms[0]) == DialogResult.Cancel)
            return false;
              consoleKey = dlg.Key;
              Properties.Settings.Default.ToxikkConsoleKey = (int) consoleKey;
              Properties.Settings.Default.Save();
            }
              }

              ThreadPool.QueueUserWorkItem(context => ConnectInBackground(server, password, spectate), null);
              return true;
        }
コード例 #4
0
        private bool UpdateServerInfo(UpdateRequest request, ServerRow row, Server server)
        {
            bool ok = ExecuteUpdate(request, row, server, retryCallback =>
            {
                var si = request.CallGetInfo || row.ServerInfo == null ? server.GetInfo(retryCallback) : row.ServerInfo;
                if (si == null)
                {
                    return(false);
                }
                row.ServerInfo = si;
                var gameId     = si.Extra.GameId;
                if (gameId == 0)
                {
                    gameId = si.Id;
                }
                if (gameId == 0)
                {
                    gameId = (int)request.AppId;
                }
                var extension = this.gameExtensions.Get((Game)gameId);
                row.SetGameExtension(extension);
                row.QueryPlayers = extension.SupportsPlayersQuery(row);
                row.QueryRules   = extension.SupportsRulesQuery(row);
                return(true);
            });

            //if (!ok)
            //  row.ServerInfo = null;
            return(ok);
        }
コード例 #5
0
        private void UpdatePlayers(UpdateRequest request, ServerRow row, Server server)
        {
            if (!row.QueryPlayers)
            {
                return;
            }
            bool ok = ExecuteUpdate(request, row, server, retryCallback =>
            {
                var sw      = (row.ServerInfo?.Ping ?? -1) == 0 ? new Stopwatch() : null;
                var players = server.GetPlayers(retryCallback, sw);
                if (players == null)
                {
                    return(false);
                }
                if (sw != null)
                {
                    row.ServerInfo.Ping = sw.ElapsedMilliseconds;
                }
                row.Players = new List <Player>(players);
                return(true);
            });

            if (!ok)
            {
                row.Players      = null;
                row.QueryPlayers = false;
            }
        }
コード例 #6
0
 public override object GetServerCellValue(ServerRow row, string fieldName)
 {
     switch (fieldName)
       {
     case "_goalscore":
     {
       var gt = row.GetRule("g_gametype");
       if (gt == "1" || gt == "2") //  DUEL, RACE
     return null;
       if (gt == "4" || gt == "9" || gt == "12") // CA, FT, RR
     return row.GetRule("roundlimit");
       if (gt == "5" || gt == "6") // CTF, 1FLAG
     return row.GetRule("capturelimit");
       if (gt == "8" || gt == "10" || gt == "11") // HAR, DOM, A&D
     return row.GetRule("scorelimit");
       return row.GetRule("fraglimit"); // 0=FFA, 3=TDM
     }
     case "_gametype":
     {
       var gt = row.GetRule("g_gametype");
       string instaPrefix = row.GetRule("g_instagib") == "1" ? "i" : "";
       int num;
       string name;
       if (int.TryParse(gt, out num) && gameTypeName.TryGetValue(num, out name))
     return instaPrefix + name;
       return instaPrefix + gt;
     }
     case "g_instagib":
       return row.GetRule(fieldName) == "1";
       }
       return base.GetServerCellValue(row, fieldName);
 }
コード例 #7
0
        private void LoadQlstatsPlayerList(ServerRow row, Action callback = null)
        {
            this.qlstatsPlayerlists[row] = null;
            using (var client = new XWebClient(2000))
            {
                client.Encoding = Encoding.UTF8;

                client.DownloadStringCompleted += (sender, args) =>
                {
                    try
                    {
                        using (var strm = new MemoryStream(Encoding.UTF8.GetBytes(args.Result)))
                        {
                            var playerList = (QlstatsPlayerList)playerListJsonParser.ReadObject(strm);
                            this.qlstatsPlayerlists[row] = playerList;
                            if (playerList.serverinfo != null)
                            {
                                this.skillInfo[row.EndPoint.ToString()] = playerList.serverinfo;
                            }
                            callback?.Invoke();
                        }
                    }
                    catch
                    {
                    }
                };

                client.DownloadStringAsync(new Uri("http://api.qlstats.net/api/server/" + row.EndPoint + "/players"));
            }
        }
コード例 #8
0
        // shared update code

        #region UpdateServerAndDetails()
        private void UpdateServerAndDetails(UpdateRequest request, ServerRow row, bool fireRefreshSingleServerComplete)
        {
            string status = "";

            try
            {
                if (request.IsCancelled)
                {
                    return;
                }

                using (Server server = ServerQuery.GetServerInstance(EngineType.Source, row.EndPoint, false, request.Timeout, request.Timeout))
                {
                    row.Retries = 0;
                    server.SendFirstPacketTwice = this.sendFirstUdpPacketTwice;
                    server.Retries = 3;
                    status         = "timeout";
                    if (this.UpdateServerInfo(request, row, server))
                    {
                        row.GameExtension = gameExtensions.Get((Game)(row.ServerInfo.Extra?.GameId ?? row.ServerInfo.Id));
                        this.UpdatePlayers(request, row, server);
                        this.UpdateRules(request, row, server);
                        status = "ok";
                    }
                    row.RequestTimestamp = request.Timestamp;
                }

                if (request.IsCancelled) // status might have changed
                {
                    return;
                }

                if (row.Retries > 0)
                {
                    status += " (" + row.Retries + ")";
                }
            }
            catch
            {
                // this happens when you hibernate windows and the program resumes before the network connection has be reestablished
                status = "network error";
            }
            finally
            {
                row.Status = status;
                row.Update();
                request.SetDataModified();

                if (fireRefreshSingleServerComplete && !request.IsCancelled)
                {
                    this.RefreshSingleServerComplete?.Invoke(this, new ServerEventArgs(row));
                }

                if (!request.PendingTasks.IsSet)
                {
                    request.PendingTasks.Signal();
                }
            }
        }
コード例 #9
0
        // ZeroMQ rcon stuff
#if ZMQ
        #region Rcon()

        public override void Rcon(ServerRow row, int port, string password, string command)
        {
            using (var ctx = ZContext.Create())
            {
                ZSocket client, monitor;
                var     endpoint = new IPEndPoint(row.EndPoint.Address, port);
                this.CreateClientAndMonitorSockets(ctx, endpoint, password, out client, out monitor);
                using (client)
                    using (monitor)
                    {
                        while (true)
                        {
                            ZMessage msg = new ZMessage();
                            ZError   err;
                            var      poll = ZPollItem.CreateReceiver();
                            var      ev   = client.Poll(poll, ZPoll.In | ZPoll.Out | ZPoll.Err, ref msg, out err, TimeSpan.FromMilliseconds(500));
                            if (err == ZError.ETERM)
                            {
                                break;
                            }

                            var evMonitor = CheckMonitor(monitor);
                            if (evMonitor != null)
                            {
                                if (evMonitor.Item1 == ZMonitorEvents.Connected)
                                {
                                    client.Send(new ZFrame("register"));
                                    client.Send(new ZFrame(command));
                                    return;
                                }
                                if (evMonitor.Item1 == ZMonitorEvents.Closed || evMonitor.Item1 == ZMonitorEvents.Disconnected)
                                {
                                    return;
                                }
                            }

                            if (!ev)
                            {
                                continue;
                            }

                            while (true)
                            {
                                client.ReceiveMessage(ref msg, ZSocketFlags.DontWait, out err);
                                if (err != ZError.None)
                                {
                                    if (err != ZError.EAGAIN)
                                    {
                                        Console.WriteLine(err);
                                    }
                                    break;
                                }
                                Console.WriteLine(msg);
                            }
                        }
                    }
            }
        }
コード例 #10
0
        public override int GetSpectatorCount(ServerRow row)
        {
            var info = this.skillInfo.GetValueOrDefault(row.EndPoint.ToString(), null);

            if (info != null)
            {
                return(info.sc);
            }
            return(0);
        }
コード例 #11
0
        public override bool SupportsPlayersQuery(ServerRow server)
        {
            // in case the matchmaking servers weren't filtered out on the server side, we also have a client-side check here
            if (server?.ServerInfo?.Extra.Keywords != null && server.ServerInfo.Extra.Keywords.Contains("valve_ds"))
            {
                return(false);
            }

            return(true);
        }
コード例 #12
0
        public override int?GetMaxPlayers(ServerRow row)
        {
            var val = row.GetRule("NumPublicConnections");

            if (val != null)
            {
                return(int.Parse(val));
            }
            return(base.GetMaxPlayers(row));
        }
コード例 #13
0
        public override int?GetBotCount(ServerRow row)
        {
            var info = this.skillInfo.GetValueOrDefault(row.EndPoint.ToString(), null);

            if (info != null)
            {
                return(info.bc);
            }
            return(base.GetRealPlayerCount(row));
        }
コード例 #14
0
 public override bool Connect(ServerRow server, string password, bool spectate)
 {
     if (useKeystrokesToConnect)
     {
         // don't use the ThreadPool b/c it might be full with waiting server update requests
         new Thread(ctx => { ConnectInBackground(server, password, spectate); }).Start();
         return(true);
     }
     return(base.Connect(server, password, spectate));
 }
コード例 #15
0
        public override int?GetRealPlayerCount(ServerRow row)
        {
            if (row.Rules == null)
            {
                return(base.GetRealPlayerCount(row));
            }

            var strSteamIds = (row.GetRule("p1073741829") ?? "") + "," + (row.GetRule("p1073741830") ?? "") + "," + (row.GetRule("p1073741831") ?? "");

            return(strSteamIds == "" ? 0 : strSteamIds.Split(',', ';').Count(id => id != ""));
        }
コード例 #16
0
        public override string GetPrettyNameForRule(ServerRow row, string ruleName)
        {
            switch (ruleName)
            {
            case MinCombatants: return("min. Combatants");

            case ScoreLimit: return("Score Limit");

            case TimeLimit: return("Time Limit");

            case Mutators: return("Mutators");

            case GameVersion: return("GameVersion");

            case OldOfficialNewRanked: return("Ranked (pre-1.1.8: Official)");

            case NewOfficial: return("Official (since 1.1.8)");

            case ModdingLevel: return("Modding level");

            case ToxikkSkillInfo.MinSkillClass: return("Min SC");

            case ToxikkSkillInfo.MaxSkillClass: return("Max SC");

            case "p1073741825": return("Map");

            case "p1073741826": return("Gametype Class");

            case "p1073741827": return("Server Description");

            case "p1073741829": return("Player IDs #1");

            case "p1073741830": return("Player IDs #2");

            case "p1073741831": return("Player IDs #3");

            case "p1073741832": return("Player names #1");

            case "p1073741833": return("Player names #2");

            case "p1073741834": return("Player names #3");

            case "p1073741837": return("Player SCs");

            case "p1073741838": return("Player ranks");

            case "s0": return("Bot difficulty");

            case "p268435706": return("Max. players");

            case "p1073741840": return("Map list");
            }
            return(null);
        }
コード例 #17
0
        public override int?GetPrivateClients(ServerRow row)
        {
            var cli = row.GetRule("sv_privateclients");
            int val;

            if (!string.IsNullOrEmpty(cli) && int.TryParse(cli, out val))
            {
                return(val);
            }

            return(0);
        }
コード例 #18
0
ファイル: Toxikk.cs プロジェクト: donkz/SteamServerBrowser
        public override void CustomizePlayerContextMenu(ServerRow server, Player player, List<PlayerContextMenuItem> menu)
        {
            this.UpdatePlayerInfos(server);
              ToxikkPlayerInfo info;
              if (!this.playerInfos.TryGetValue(player.Name, out info))
            return;

              menu.Insert(0, new PlayerContextMenuItem("Open Steam Chat", () => { Process.Start("steam://friends/message/" + info.SteamId); }, true));
              menu.Insert(1, new PlayerContextMenuItem("Show Steam Profile", () => { Process.Start("http://steamcommunity.com/profiles/" + info.SteamId + "/"); }));
              menu.Insert(2, new PlayerContextMenuItem("Add to Steam Friends", () => { Process.Start("steam://friends/add/" + info.SteamId); }));
              menu.Add(new PlayerContextMenuItem("Copy Steam-ID to Clipboard", () => { Clipboard.SetText(info.SteamId); }));
        }
コード例 #19
0
        // refresh single server

        #region RefreshSingleServer()
        public void RefreshSingleServer(ServerRow row)
        {
            if (this.IsUpdating)
            {
                return;
            }
            row.Status = "updating...";
            var req = new UpdateRequest(this.currentRequest.AppId, 1, this.currentRequest.Timeout, this.currentRequest.GameExtension, true);

            req.PendingTasks    = new CountdownEvent(1);
            this.currentRequest = req;
            ThreadPool.QueueUserWorkItem(dummy => this.UpdateServerAndDetails(req, row, true));
        }
コード例 #20
0
        public override int?GetMaxClients(ServerRow row)
        {
            var cli = row.GetRule("sv_maxclients");
            int val;

            if (!string.IsNullOrEmpty(cli) && int.TryParse(cli, out val))
            {
                return(val);
            }

            // QL currently returns the sv_maxclients in MaxPlayers (instead of teamsize * 2)
            return(row.ServerInfo?.MaxPlayers);
        }
コード例 #21
0
        public override bool FilterServerRow(ServerRow row)
        {
            if (this.skillClassFilter == 0 || row.Rules == null)
            {
                return(false);
            }

            // remove server rows which are outside the skill class
            var min = int.Parse(row.GetRule(ToxikkSkillInfo.MinSkillClass));
            var max = int.Parse(row.GetRule(ToxikkSkillInfo.MaxSkillClass));

            return(this.skillClassFilter < min || this.skillClassFilter > max);
        }
コード例 #22
0
 public override void Refresh(ServerRow row = null, Action callback = null)
 {
     LoadQlstatsPersonalRating();
     LoadQlstatsServerRatings();
     if (row == null)
     {
         this.qlstatsPlayerlists.Clear();
     }
     else
     {
         this.LoadQlstatsPlayerList(row, callback);
     }
 }
コード例 #23
0
        public override void CustomizePlayerContextMenu(ServerRow server, Player player, List <PlayerContextMenuItem> menu)
        {
            this.UpdatePlayerInfos(server);
            ToxikkPlayerInfo info;

            if (!this.playerInfos.TryGetValue(player.Name, out info))
            {
                return;
            }

            menu.Insert(0, new PlayerContextMenuItem("Open Steam Chat", () => { Process.Start("steam://friends/message/" + info.SteamId); }, true));
            menu.Insert(1, new PlayerContextMenuItem("Show Steam Profile", () => { Process.Start("http://steamcommunity.com/profiles/" + info.SteamId + "/"); }));
            menu.Insert(2, new PlayerContextMenuItem("Add to Steam Friends", () => { Process.Start("steam://friends/add/" + info.SteamId); }));
            menu.Add(new PlayerContextMenuItem("Copy Steam-ID to Clipboard", () => { Clipboard.SetText(info.SteamId); }));
        }
コード例 #24
0
        public override bool IsValidPlayer(ServerRow server, Player player)
        {
            var list = qlstatsPlayerlists.GetValueOrDefault(server, null);

            if (list?.players != null)
            {
                var cleanName = this.GetCleanPlayerName(player.Name, true);
                return(list.players.Count(p => this.GetCleanPlayerName(p.name) == cleanName) > 0);
            }

            // hack to remove ghost players which are not really on the server
            var status = server.GetRule("g_gameStatus");

            return(status != "IN_PROGRESS" || player.Score > 0 || player.Time < TimeSpan.FromHours(1));
        }
コード例 #25
0
        public override object GetServerCellValue(ServerRow row, string fieldName)
        {
            if (fieldName == "_gametype")
            {
                var parts = row.ServerInfo?.Extra.Keywords?.Split(',', '|');
                return(parts?[0]);
            }
            if (fieldName == "_location")
            {
                var parts = row.ServerInfo?.Extra.Keywords?.Split(',', '|');
                return(parts?.Length > 1 ? parts[1] : null);
            }

            return(base.GetServerCellValue(row, fieldName));
        }
コード例 #26
0
        public override int?GetBotCount(ServerRow row)
        {
            if (row.ServerInfo == null)
            {
                return(null);
            }
            int bots = row.ServerInfo.Bots;

            if (bots != 0)
            {
                return(bots);
            }
            if (row.Rules != null && int.TryParse(row.GetRule(MinCombatants), out bots))
            {
                return(bots);
            }
            return(0);
        }
コード例 #27
0
        private decimal GetBestPlayerSC(ServerRow row)
        {
            if (row.Players == null || row.Rules == null)
            {
                return(0);
            }
            decimal maxSc = 0;

            foreach (var player in row.Players)
            {
                var sc = this.GetPlayerCellValue(row, player, "SC");
                if (sc is decimal)
                {
                    maxSc = Math.Max(maxSc, (decimal)sc);
                }
            }
            return(maxSc);
        }
コード例 #28
0
ファイル: Reflex.cs プロジェクト: vtchill/SteamServerBrowser
        public override object GetServerCellValue(ServerRow row, string fieldName)
        {
            if (fieldName == "_gametype")
              {
            if (row.ServerInfo == null || row.ServerInfo.Extra == null || row.ServerInfo.Extra.Keywords == null)
              return null;
            var parts = row.ServerInfo.Extra.Keywords.Split('|');
            return parts[0];
              }
              if (fieldName == "_location")
              {
            if (row.ServerInfo == null || row.ServerInfo.Extra == null || row.ServerInfo.Extra.Keywords == null)
              return null;
            var parts = row.ServerInfo.Extra.Keywords.Split('|');
            return parts.Length > 1 ? parts[1] : null;
              }

              return base.GetServerCellValue(row, fieldName);
        }
コード例 #29
0
        public override bool Connect(ServerRow server, string password, bool spectate)
        {
            if (this.startExtraQL)
            {
                var extraQlExe = this.GetExtaQlPath();
                if (extraQlExe != null)
                {
                    Process.Start(extraQlExe, "-background");
                }
            }

            if (this.useKeystrokesToConnect)
            {
                // don't use the ThreadPool b/c it might be full with waiting server update requests
                new Thread(ctx => { ConnectInBackground(server, password, spectate); }).Start();
                return(true);
            }

            return(base.Connect(server, password, spectate));
        }
コード例 #30
0
        public override int?GetRealPlayerCount(ServerRow row)
        {
            var info = this.skillInfo.GetValueOrDefault(row.EndPoint.ToString(), null);

            if (info != null)
            {
                return(info.pc + info.sc);
            }

            // minqlx bots are not correctly counted as bots in the server info
            if (row.Players != null)
            {
                var c = row.Players.Count(p => p.Name.StartsWith("(Bot)"));
                if (c > 0)
                {
                    return(row.Players.Count - c);
                }
            }

            return(base.GetRealPlayerCount(row));
        }
コード例 #31
0
        public override object GetPlayerCellValue(ServerRow server, Player player, string fieldName)
        {
            if (fieldName[0] != '_')
            {
                return(base.GetPlayerCellValue(server, player, fieldName));
            }

            QlstatsPlayerList list;

            QlstatsPlayerList.Player playerInfo = null;
            this.qlstatsPlayerlists.TryGetValue(server, out list);
            if (list?.players != null)
            {
                var cleanName = this.GetCleanPlayerName(player.Name, true);
                playerInfo = list.players.FirstOrDefault(p => this.GetCleanPlayerName(p.name) == cleanName);
            }
            if (playerInfo == null)
            {
                if (fieldName == "_time")
                {
                    return(player.Time.ToString("hh\\:mm\\:ss"));
                }
                return(null);
            }

            if (fieldName == "_team")
            {
                return(TeamNames[playerInfo.team + 1]);
            }
            if (fieldName == "_skill")
            {
                return(playerInfo.rating); //(playerInfo.rating+50)/100;
            }
            if (fieldName == "_time")
            {
                return((DateTime.UtcNow - new DateTime(1970, 1, 1).AddMilliseconds(playerInfo.time)).ToString("hh\\:mm\\:ss"));
            }

            return(null);
        }
コード例 #32
0
        public override void CustomizePlayerContextMenu(ServerRow server, Player player, List <PlayerContextMenuItem> menu)
        {
            QlstatsPlayerList list;

            if (!this.qlstatsPlayerlists.TryGetValue(server, out list) || list.players == null)
            {
                return;
            }
            var cleanName = this.GetCleanPlayerName(player);
            var info      = list.players.FirstOrDefault(p => this.GetCleanPlayerName(p.name) == cleanName);

            if (info == null)
            {
                return;
            }

            menu.Insert(0, new PlayerContextMenuItem("Open Steam Chat", () => { Process.Start("steam://friends/message/" + info.steamid); }, true));
            menu.Insert(1, new PlayerContextMenuItem("Show Steam Profile", () => { Process.Start("http://steamcommunity.com/profiles/" + info.steamid + "/"); }));
            menu.Insert(2, new PlayerContextMenuItem("Show QLStats Profile", () => { Process.Start("http://qlstats.net/player/" + info.steamid); }));
            menu.Insert(3, new PlayerContextMenuItem("Add to Steam Friends", () => { Process.Start("steam://friends/add/" + info.steamid); }));
            menu.Add(new PlayerContextMenuItem("Copy Steam-ID to Clipboard", () => { Clipboard.SetText(info.steamid); }));
        }
コード例 #33
0
        private void ConnectInBackground(ServerRow server, string password, bool spectate)
        {
            var hWnd = FindGameWindow();

            if (hWnd == IntPtr.Zero)
            {
                hWnd = StartQuakeLive();
                if (hWnd == IntPtr.Zero)
                {
                    return;
                }
                SkipIntro(hWnd);
            }

            // console key
            Win32.PostMessage(hWnd, Win32.WM_KEYDOWN, 0, 0x29 << 16);
            Win32.PostMessage(hWnd, Win32.WM_KEYUP, 0, 0x29 << 16);

            Thread.Sleep(100);

            var msg = "/";

            if (!string.IsNullOrEmpty(password))
            {
                msg += "set password \"" + password + "\";";
            }
            msg += "connect " + server.EndPoint.Address + ":" + server.ServerInfo.Extra.Port;
            foreach (var c in msg)
            {
                Win32.PostMessage(hWnd, Win32.WM_CHAR, c, 0);
                Thread.Sleep(10);
            }

            Win32.PostMessage(hWnd, Win32.WM_KEYDOWN, (int)Keys.Return, 0x1C << 16);
            Win32.PostMessage(hWnd, Win32.WM_KEYUP, (int)Keys.Return, 0x1C << 16);

            this.ActivateGameWindow(hWnd);
        }
コード例 #34
0
        public override bool Connect(ServerRow server, string password, bool spectate)
        {
            if (consoleKey == Keys.None && (this.useKeystrokesToConnect || spectate))
            {
                using (var dlg = new KeyBindForm("Please press your TOXIKK console key..."))
                {
                    if (dlg.ShowDialog(Application.OpenForms[0]) == DialogResult.Cancel)
                    {
                        return(false);
                    }
                    this.consoleKey = dlg.Key;
                }
            }

            if (this.useKeystrokesToConnect || spectate)
            {
                // don't use the ThreadPool b/c it might be full with waiting server update requests
                new Thread(ctx => { ConnectInBackground(server, password, spectate); }).Start();
                return(true);
            }

            return(base.Connect(server, password, false));
        }
コード例 #35
0
 private void UpdateRules(UpdateRequest request, ServerRow row, Server server)
 {
     if (!request.QueryServerRules)
     return;
       bool ok = ExecuteUpdate(request, row, server, retryCallback =>
       {
     row.Rules = new List<Rule>(server.GetRules(retryCallback));
       });
       if (!ok)
     row.Rules = null;
 }
コード例 #36
0
 private void UpdatePlayers(UpdateRequest request, ServerRow row, Server server)
 {
     bool ok = ExecuteUpdate(request, row, server, retryCallback =>
       {
     var players = server.GetPlayers(retryCallback);
     row.Players = players == null ? null : new List<Player>(players);
       });
       if (!ok)
     row.Players = null;
 }
コード例 #37
0
        /// <summary>
        /// Template method for common code needed in UpdateServerInfo, UpdatePlayers and UpdateRules
        /// </summary>
        private bool ExecuteUpdate(UpdateRequest request, ServerRow row, Server server, Action<Action<int>> updater)
        {
            if (request.IsCancelled)
            return false;

              try
              {
            row.Status = "updating " + row.Retries;
            request.DataModified = 1;
            updater(retry =>
            {
              if (request.IsCancelled)
            throw new OperationCanceledException();
              if (row.Retries == 0)
            Interlocked.Increment(ref request.TasksWithRetries);
              row.Status = "updating " + (++row.Retries + 1);
              request.DataModified = 1;
            });
            return true;
              }
              catch (TimeoutException)
              {
            return false;
              }
              catch
              {
            return true;
              }
        }
コード例 #38
0
        private void btnAddGameServer_Click(object sender, EventArgs e)
        {
            try
              {
            string[] parts = this.txtServerQuery.Text.Split(':');

            var addr = Dns.GetHostAddresses(parts[0]);
            if (addr.Length == 0) return;
            var endpoint = new IPEndPoint(addr[0], parts.Length > 1 ? int.Parse(parts[1]) : 25785);
            ServerRow serverRow = null;
            foreach (var row in this.servers)
            {
              if (row.EndPoint.Equals(endpoint))
              {
            serverRow = row;
            break;
              }
            }

            if (serverRow == null)
            {
              this.gvServers.BeginDataUpdate();
              serverRow = new ServerRow(endpoint);
              this.servers.Add(serverRow);
              this.gvServers.EndDataUpdate();
              this.gvServers.FocusedRowHandle = this.gvServers.GetRowHandle(this.servers.Count - 1);
            }
            this.queryLogic.RefreshSingleServer(serverRow);
              }
              catch
              {
              }
        }
コード例 #39
0
 private void SendRconCommand(ServerRow row, int port, string pass, string text)
 {
     row.GameExtension?.Rcon(row, port, pass, text);
 }
コード例 #40
0
        private void SetViewModel(TabViewModel vm)
        {
            this.viewModel = vm;
              if (vm.Source == TabViewModel.SourceType.Favorites)
              {
            vm.servers = new List<ServerRow>();
            foreach (var fav in this.favServers)
            {
              var row = new ServerRow(fav.Key, this.extenders.Get(0));
              row.CachedName = fav.Value;
              vm.servers.Add(row);
            }
              }

              var info = vm.MasterServer;
              if (string.IsNullOrEmpty(info))
            info = "hl2master.steampowered.com:27011";
              this.comboMasterServer.Text = info;
              this.SetSteamAppId(vm.InitialGameID);
              this.txtTagInclude.Text = vm.TagsInclude;
              this.txtTagExclude.Text = vm.TagsExclude;
              this.txtMod.Text = vm.FilterMod;
              this.txtMap.Text = vm.FilterMap;
              this.cbGetEmpty.Checked = vm.GetEmptyServers;
              this.cbGetFull.Checked = vm.GetFullServers;
              this.comboQueryLimit.Text = vm.MasterServerQueryLimit.ToString();

              this.gvServers.ActiveFilterString = vm.GridFilter;

              UpdatePanelVisibility();
              this.miFindServers.Enabled = vm.Source == TabViewModel.SourceType.MasterServer;
        }
コード例 #41
0
        private void ConnectToGameServer(ServerRow row, bool spectate)
        {
            if (row?.ServerInfo == null)
            return;

              string password = null;
              if (row.ServerInfo.IsPrivate)
              {
            password = this.PromptForServerPassword(row);
            if (password == null)
              return;
              }

              this.Cursor = Cursors.WaitCursor;
              this.SetStatusMessage("Connecting to game server " + row.ServerInfo.Name + " ...");
              row.GameExtension.Connect(row, password, spectate);
              this.Cursor = Cursors.Default;
        }
コード例 #42
0
        private bool ConnectInBackground(ServerRow server, string password, bool spectate)
        {
            var win = FindQuakeWindow();
              if (win == IntPtr.Zero)
              {
            win = StartQuakeLive();
            if (win == IntPtr.Zero)
              return false;
            SkipIntro(win);
              }

              // console key
              Win32.PostMessage(win, Win32.WM_KEYDOWN, 0, 0x29 << 16);
              Win32.PostMessage(win, Win32.WM_KEYUP, 0, 0x29 << 16);

              Thread.Sleep(100);

              var msg = "/";
              if (!string.IsNullOrEmpty(password))
            msg += "set password \"" + password + "\";";
              msg += "connect " + server.EndPoint.Address + ":" + server.ServerInfo.Extra.Port;
              foreach (var c in msg)
              {
            Win32.PostMessage(win, Win32.WM_CHAR, c, 0);
            Thread.Sleep(10);
              }

              Win32.PostMessage(win, Win32.WM_KEYDOWN, (int) Keys.Return, 0x1C << 16);
              Win32.PostMessage(win, Win32.WM_KEYUP, (int) Keys.Return, 0x1C << 16);

              return true;
        }
コード例 #43
0
        public override void Rcon(ServerRow row, int port, string password, string command)
        {
            using (var ctx = ZContext.Create())
              {
            ZSocket client, monitor;
            var endpoint = new IPEndPoint(row.EndPoint.Address, port);
            this.CreateClientAndMonitorSockets(ctx, endpoint, password, out client, out monitor);
            using (client)
            using (monitor)
            {
              while (true)
              {
            ZMessage msg = new ZMessage();
            ZError err;
            var poll = ZPollItem.CreateReceiver();
            var ev = client.Poll(poll, ZPoll.In | ZPoll.Out | ZPoll.Err, ref msg, out err, TimeSpan.FromMilliseconds(500));
            if (err == ZError.ETERM)
              break;

            var evMonitor = CheckMonitor(monitor);
            if (evMonitor != null)
            {
              if (evMonitor.Item1 == ZMonitorEvents.Connected)
              {
                client.Send(new ZFrame("register"));
                client.Send(new ZFrame(command));
                return;
              }
              if (evMonitor.Item1 == ZMonitorEvents.Closed || evMonitor.Item1 == ZMonitorEvents.Disconnected)
                return;
            }

            if (!ev)
              continue;

            while (true)
            {
              client.ReceiveMessage(ref msg, ZSocketFlags.DontWait, out err);
              if (err != ZError.None)
              {
                if (err != ZError.EAGAIN)
                  Console.WriteLine(err);
                break;
              }
              Console.WriteLine(msg);
            }
              }
            }
              }
        }
コード例 #44
0
        private void gvServers_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            try
              {
            var row = (ServerRow)this.gvServers.GetFocusedRow();
            if (row == null || row == this.lastSelectedServer) // prevent consecutive updates due to row-reordering
              return;

            if (this.ignoreUiEvents == 0)
              this.lastSelectedServer = row;

            this.UpdateGridDataSources();

            if (!this.cbRefreshSelectedServer.Checked)
              return;

            if (this.queryLogic.IsUpdating)
              return;

            Application.DoEvents();
            this.queryLogic.RefreshSingleServer(row);
              }
              catch (Exception ex)
              {
            this.txtStatus.Text = ex.Message;
              }
        }
コード例 #45
0
 private string GetServerAddress(ServerRow row)
 {
     return this.showGamePortInAddress && row.ServerInfo != null && row.ServerInfo.Extra != null
     ? row.EndPoint.Address + ":" + row.ServerInfo.Extra.Port
     : row.EndPoint.ToString();
 }
コード例 #46
0
        private void ConnectToGameServer(ServerRow row, bool spectate)
        {
            if (row.ServerInfo == null)
            return;

              string password = null;
              if (row.ServerInfo.IsPrivate)
              {
            if (this.passwordForm.ShowDialog(this) == DialogResult.Cancel)
              return;
            password = this.passwordForm.Password;
              }

              this.Cursor = Cursors.WaitCursor;
              this.gameExtension.Connect(row, password, spectate);
              this.Cursor = Cursors.Default;
        }
コード例 #47
0
        private void UpdateServerAndDetails(UpdateRequest request, ServerRow row, bool fireRefreshSingleServerComplete)
        {
            try
              {
            if (request.IsCancelled)
              return;

            string status;
            using (Server server = ServerQuery.GetServerInstance(EngineType.Source, row.EndPoint, false, 500, 500))
            {
              row.Retries = 0;
              server.SendFirstPacketTwice = this.sendFirstUdpPacketTwice;
              server.Retries = 3;
              status = "timeout";
              if (this.UpdateServerInfo(request, row, server))
              {
            this.UpdatePlayers(request, row, server);
            this.UpdateRules(request, row, server);
            status = "ok";
              }
              row.RequestTimestamp = request.Timestamp;
            }

            if (request.IsCancelled) // status might have changed
              return;

            if (row.Retries > 0)
              status += " (" + row.Retries + ")";
            row.Status = status;
            row.Update();
            request.DataModified = 1;

            if (fireRefreshSingleServerComplete && this.RefreshSingleServerComplete != null)
              this.RefreshSingleServerComplete(this, new ServerEventArgs(row));
              }
              finally
              {
            request.PendingTasks.Signal();
              }
        }
コード例 #48
0
 private void GeoIpReceived(ServerRow server, GeoInfo geoInfo)
 {
     server.GeoInfo = geoInfo;
       Interlocked.Exchange(ref this.geoIpModified, 1);
 }
コード例 #49
0
 private bool UpdateServerInfo(UpdateRequest request, ServerRow row, Server server)
 {
     bool ok = ExecuteUpdate(request, row, server, retryCallback =>
       {
     row.ServerInfo = server.GetInfo(retryCallback);
       });
       if (!ok)
     row.ServerInfo = null;
       return ok;
 }
コード例 #50
0
        public void LoadFromIni(IniFile iniFile, IniFile.Section ini, GameExtensionPool pool)
        {
            this.Source = (SourceType) ini.GetInt("Type");
              this.MasterServer = ini.GetString("MasterServer") ?? "hl2master.steampowered.com:27011";
              this.InitialGameID = ini.GetInt("InitialGameID");
              this.FilterMod = ini.GetString("FilterMod");
              this.FilterMap = ini.GetString("FilterMap");
              this.TagsInclude = ini.GetString("TagsInclude");
              this.TagsExclude = ini.GetString("TagsExclude");
              this.GetEmptyServers = ini.GetBool("GetEmptyServers", true);
              this.GetFullServers = ini.GetBool("GetFullServers", true);
              this.MasterServerQueryLimit = ini.GetInt("MasterServerQueryLimit", 500);
              this.GridFilter = ini.GetString("GridFilter");

              var layout = ini.GetString("GridLayout");
              if (!string.IsNullOrEmpty(layout))
            this.ServerGridLayout = new MemoryStream(Convert.FromBase64String(layout));

              this.gameExtension = pool.Get((Game) this.InitialGameID);

              if (this.Source == SourceType.CustomList)
              {
            this.servers = new List<ServerRow>();

            // new config format
            var sec = iniFile.GetSection(ini.Name + "_Servers");
            if (sec != null)
            {
              foreach (var key in sec.Keys)
              {
            var row = new ServerRow(Ip4Utils.ParseEndpoint(key), this.gameExtension);
            row.CachedName = sec.GetString(key);
            this.servers.Add(row);
              }
            }
            else
            {
              // old config format
              var oldSetting = ini.GetString("Servers") ?? "";
              foreach (var server in oldSetting.Split('\n', ' '))
              {
            var s = server.Trim();
            if (s == "") continue;
            this.servers.Add(new ServerRow(Ip4Utils.ParseEndpoint(s), this.gameExtension));
              }
            }
              }
        }
コード例 #51
0
 private bool UpdateServerInfo(UpdateRequest request, ServerRow row, Server server)
 {
     bool ok = ExecuteUpdate(request, row, server, retryCallback =>
       {
     row.ServerInfo = server.GetInfo(retryCallback);
     if (row.ServerInfo == null)
       return false;
     var gameId = row.ServerInfo.Extra?.GameId ?? 0;
     if (gameId == 0) gameId = row.ServerInfo.Id;
     if (gameId == 0) gameId = (int)request.AppId;
     var extension = this.gameExtensions.Get((Game)gameId);
     row.GameExtension = extension;
     row.QueryPlayers = extension.SupportsPlayersQuery(row);
     row.QueryRules = extension.SupportsRulesQuery(row);
     return true;
       });
       if (!ok)
     row.ServerInfo = null;
       return ok;
 }
コード例 #52
0
 public void RefreshSingleServer(ServerRow row)
 {
     row.Status = "updating...";
       this.currentRequest = new UpdateRequest(1, this.currentRequest.QueryServerRules);
       this.currentRequest.PendingTasks = new CountdownEvent(1);
       ThreadPool.QueueUserWorkItem(dummy => this.UpdateServerAndDetails(this.currentRequest, row, true));
 }
コード例 #53
0
        private void UpdateServerAndDetails(UpdateRequest request, ServerRow row, bool fireRefreshSingleServerComplete)
        {
            string status = "";
              try
              {
            if (request.IsCancelled)
              return;

            using (Server server = ServerQuery.GetServerInstance(EngineType.Source, row.EndPoint, false, request.Timeout, request.Timeout))
            {
              row.Retries = 0;
              server.SendFirstPacketTwice = this.sendFirstUdpPacketTwice;
              server.Retries = 3;
              status = "timeout";
              var oldPing = row.ServerInfo?.Ping ?? 0;
              if (this.UpdateServerInfo(request, row, server))
              {
            if (request.KeepPreviousPing && row.ServerInfo != null)
              row.ServerInfo.Ping = oldPing; // keep old ping so that the row isn't immediately resorted and moved
            this.UpdatePlayers(request, row, server);
            this.UpdateRules(request, row, server);
            status = "ok";
              }
              row.RequestTimestamp = request.Timestamp;
            }

            if (request.IsCancelled) // status might have changed
              return;

            if (row.Retries > 0)
              status += " (" + row.Retries + ")";
              }
              catch
              {
            // this happens when you hibernate windows and the program resumes before the network connection has be reestablished
            status = "network error";
              }
              finally
              {
            row.Status = status;
            row.Update();
            request.SetDataModified();

            if (fireRefreshSingleServerComplete)
              this.RefreshSingleServerComplete?.Invoke(this, new ServerEventArgs(row));

            if (!request.PendingTasks.IsSet)
              request.PendingTasks.Signal();
              }
        }
コード例 #54
0
 public ServerEventArgs(ServerRow server)
 {
     this.Server = server;
 }
コード例 #55
0
 public override bool Connect(ServerRow server, string password, bool spectate)
 {
     ThreadPool.QueueUserWorkItem(context => ConnectInBackground(server, password, spectate), null);
       return true;
       //return base.Connect(server, password, spectate);
 }
コード例 #56
0
 private string GetServerAddress(ServerRow row)
 {
     return this.showAddressMode == 2 && row.ServerInfo?.Extra != null
     ? row.EndPoint.Address + ":" + row.ServerInfo.Extra.Port
     : row.EndPoint.ToString();
 }
コード例 #57
0
        private void txtGameServer_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            try
              {
            string[] parts = this.txtGameServer.Text.Split(':');
            if (parts[0].Length == 0) return;
            // get IPv4 address
            var addr = Dns.GetHostAddresses(parts[0]);
            int i;
            for (i = 0; i < addr.Length; i++)
            {
              if (addr[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            break;
            }
            if (i >= addr.Length) return;
            var endpoint = new IPEndPoint(addr[i], parts.Length > 1 ? int.Parse(parts[1]) : 27015);
            if (endpoint.Address.ToString() == "0.0.0.0") return;
            ServerRow serverRow = null;
            foreach (var row in this.viewModel.servers)
            {
              if (row.EndPoint.Equals(endpoint))
              {
            serverRow = row;
            break;
              }
            }

            if (serverRow == null)
            {
              this.gvServers.BeginDataUpdate();
              serverRow = new ServerRow(endpoint, this.extenders.Get(0));
              this.viewModel.servers.Add(serverRow);
              this.gvServers.EndDataUpdate();
              var handle = this.gvServers.GetRowHandle(this.viewModel.servers.Count - 1);
              this.gvServers.FocusedRowHandle = handle;
              this.gvServers.SelectRow(handle);
            }
            this.queryLogic.RefreshSingleServer(serverRow);
              }
              catch
              {
              }
        }
コード例 #58
0
 public override object GetPlayerCellValue(ServerRow server, Player player, string fieldName)
 {
     if (fieldName == "NameWithoutColorCodes")
     return NameColors.Replace(player.Name, "");
       return base.GetPlayerCellValue(server, player, fieldName);
 }
コード例 #59
0
 public PlayerCountInfo(ServerRow row)
 {
     this.row = row;
       this.Update();
 }
コード例 #60
0
 protected virtual string PromptForServerPassword(ServerRow row)
 {
     if (this.passwordForm.ShowDialog(this) == DialogResult.Cancel)
     return null;
       return this.passwordForm.Password;
 }