예제 #1
0
        public void Update()
        {
            this.HighestPlayerSkill = 0;
            this.Min = 0;
            this.Max = 0;

            int num;

            if (int.TryParse(row.GetRule(MinSkillClass), out num))
            {
                this.Min = num;
            }
            if (int.TryParse(row.GetRule(MaxSkillClass), out num))
            {
                this.Max = num;
            }

            if (row.Rules == null || row.Players == null)
            {
                return;
            }

            decimal maxSc = 0;

            foreach (var player in row.Players)
            {
                var sc = this.extension.GetPlayerCellValue(row, player, "SC");
                if (sc is decimal)
                {
                    maxSc = Math.Max(maxSc, (decimal)sc);
                }
            }
            this.HighestPlayerSkill = maxSc;
        }
예제 #2
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 != ""));
        }
예제 #3
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);
        }
예제 #4
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);
 }
예제 #5
0
        public override int?GetMaxPlayers(ServerRow row)
        {
            var val = row.GetRule("NumPublicConnections");

            if (val != null)
            {
                return(int.Parse(val));
            }
            return(base.GetMaxPlayers(row));
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #8
0
        public override int?GetMaxPlayers(ServerRow row)
        {
            var gt = row.GetRule("g_gametype");

            if (gt == "1") // Duel
            {
                return(2);
            }

            var ts = row.GetRule("teamsize");

            if (!string.IsNullOrEmpty(ts))
            {
                int n;
                int.TryParse(ts, out n);
                if (n != 0)
                {
                    return(gt == "0" || gt == "2" ? n : n *2); // FFA, Race
                }
            }

            // QL currently returns the sv_maxclients in MaxPlayers (instead of teamsize * 2)
            return(row.ServerInfo?.MaxPlayers);
        }
예제 #9
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));
        }
예제 #10
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);
        }
예제 #11
0
        private void UpdatePlayerInfos(ServerRow server)
        {
            // no need for update if it's the same server and update timestamp
            if (server == this.serverForPlayerInfos && server.RequestTimestamp == this.dataTimestamp && this.playerInfos.Count > 0)
            {
                return;
            }

            this.serverForPlayerInfos = server;
            this.dataTimestamp        = server.RequestTimestamp;
            var newPlayerInfos = new Dictionary <string, ToxikkPlayerInfo>();

            var strNames = (server.GetRule("p1073741832") ?? "") + (server.GetRule("p1073741833") ?? "") + (server.GetRule("p1073741834") ?? "");

            if (string.IsNullOrEmpty(strNames))
            {
                return;
            }
            var  gameType    = (string)server.GetExtenderCellValue("_gametype");
            bool isTeamGame  = "SA,CC,AD,SS,TA,SB,IB,2v2,4v4".Contains(gameType);
            var  strSteamIds = (server.GetRule("p1073741829") ?? "") + (server.GetRule("p1073741830") ?? "") + (server.GetRule("p1073741831") ?? "");
            var  strSkill    = server.GetRule("p1073741837") ?? "";
            var  strRank     = server.GetRule("p1073741838") ?? "";
            int  teamSepIdx  = strNames.IndexOf(';');
            var  names       = strNames.Split(',', ';');
            var  steamIds    = strSteamIds.Split(',', ';');
            var  skills      = strSkill.Split(',', ';');
            var  ranks       = strRank.Split(',', ';');
            int  i           = 0;

            foreach (var name in names)
            {
                var info = new ToxikkPlayerInfo();
                info.Team = !isTeamGame ? "Player" : teamSepIdx < 0 || strNames.IndexOf(name) < teamSepIdx ? "Red" : "Blue";
                if (i < steamIds.Length)
                {
                    info.SteamId = steamIds[i];
                }

                decimal sc;
                if (i < skills.Length && decimal.TryParse(skills[i], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out sc))
                {
                    info.SkillClass = sc;
                }
                if (i < ranks.Length && ranks[i].Length > 0)
                {
                    int rank;
                    if (!char.IsDigit(ranks[i][0]))
                    {
                        var teamInfo = ranks[i][0];
                        if (teamInfo == 29 || teamInfo == 'S')
                        {
                            info.Team = "Spec";
                        }
                        else if (teamInfo == 30 || teamInfo == 'Q')
                        {
                            info.Team = "Queue";
                        }
                        int.TryParse(ranks[i].Substring(1), out rank);
                    }
                    else
                    {
                        int.TryParse(ranks[i], out rank);
                    }
                    info.Rank = rank;
                }
                newPlayerInfos.Add(name, info);
                ++i;
            }
            this.playerInfos = newPlayerInfos;
            server.PlayerCount.Update();
        }
예제 #12
0
        private void ConnectInBackground(ServerRow server, string password, bool spectate)
        {
            var  procList  = Process.GetProcessesByName("toxikk");
            bool mustStart = procList.All(p => p.MainWindowTitle.Contains("players)") || p.Threads.Count == 0);

            if (mustStart)
            {
                StartToxikk();
            }

            IntPtr hWnd = IntPtr.Zero;

            for (int i = 0; i < SecondsToWaitForMainWindowAfterLaunch; i++)
            {
                hWnd = FindGameWindow();
                if (hWnd != IntPtr.Zero)
                {
                    break;
                }
                Thread.Sleep(1000);
            }

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

            if (mustStart)
            {
                SkipIntro(hWnd);
            }

            // open the console command line
            Win32.PostMessage(hWnd, Win32.WM_KEYDOWN, (int)consoleKey, 0);
            Win32.PostMessage(hWnd, Win32.WM_KEYUP, (int)consoleKey, 0);

            Thread.Sleep(250);

            // hack: prevent WM_DEADCHAR quirks that might be a side-effect of the console key
            Win32.PostMessage(hWnd, Win32.WM_CHAR, ' ', 0);
            for (int i = 0; i < 3; i++)
            {
                Win32.PostMessage(hWnd, Win32.WM_KEYDOWN, (int)Keys.Back, 0);
                Win32.PostMessage(hWnd, Win32.WM_CHAR, 8, 0);
                Win32.PostMessage(hWnd, Win32.WM_KEYUP, (int)Keys.Back, 0);
            }

            // send the command string
            var  msg          = "open ";
            bool steamSockets = server.Rules == null || !string.IsNullOrEmpty(server.GetRule("SteamServerId"));

            if ((useSteamIdToConnect && steamSockets || server.Rules == null || server.Players == null) && server.ServerInfo.Extra.SteamID != 0)
            {
                msg += "steam." + server.ServerInfo.Extra.SteamID;
            }
            else
            {
                msg += server.EndPoint.Address + ":" + server.ServerInfo.Extra.Port;
            }
            if (!string.IsNullOrEmpty(password))
            {
                msg += "?password="******"?spectatoronly=1";
            }
            foreach (var c in msg)
            {
                Win32.PostMessage(hWnd, Win32.WM_CHAR, c, 0);
            }

            Thread.Sleep(750);

            // and press Enter
            Win32.PostMessage(hWnd, Win32.WM_KEYDOWN, (int)Keys.Return, 0);
            Win32.PostMessage(hWnd, Win32.WM_KEYUP, (int)Keys.Return, 0);

            this.ActivateGameWindow(hWnd);
        }
예제 #13
0
 public override object GetServerCellValue(ServerRow row, string fieldName)
 {
     switch (fieldName)
       {
     case "_skillclass":
       return row.GetRule(ToxikkSkillInfo.MinSkillClass) + "-" + row.GetRule(ToxikkSkillInfo.MaxSkillClass);
       //return new ToxikkSkillInfo(row, this);
     case "_best":
       return Math.Round(this.GetBestPlayerSC(row), 1, MidpointRounding.AwayFromZero);
     case IsOfficial:
       return row.GetRule(fieldName) == "1";
     case "_gametype":
       var gt = row.ServerInfo.Description;
       return gt == null ? null : gt.Contains("BloodLust") ? "BL" : gt.Contains("TeamGame") ? "SA" : gt.Contains("Cell") ? "CC"
     : gt.Contains("TRGame") ? "TR" : gt.Contains("TAGame") ? "TA" : gt;
     case Mutators:
       var mods = (row.GetRule(fieldName) ?? "").ToLower();
       var buff = new StringBuilder();
       foreach (var mod in mods.Split('\x1c'))
       {
     if (mod.Length == 0) continue;
     if (buff.Length > 0) buff.Append(", ");
     foreach (var word in mod.Split(' '))
       buff.Append(char.ToUpper(word[0])).Append(word.Substring(1));
       }
       return buff.ToString();
       }
       return base.GetServerCellValue(row, fieldName);
 }
예제 #14
0
        private void UpdatePlayerInfos(ServerRow server)
        {
            // no need for update if it's the same server and update timestamp
              if (server == this.serverForPlayerInfos && server.RequestTimestamp == this.dataTimestamp && playerInfos.Count > 0)
            return;

              this.serverForPlayerInfos = server;
              this.dataTimestamp = server.RequestTimestamp;
              this.playerInfos.Clear();

              var strNames = (server.GetRule("p1073741832") ?? "") + (server.GetRule("p1073741833") ?? "") + (server.GetRule("p1073741834") ?? "");
              if (string.IsNullOrEmpty(strNames))
            return;
              var gameType = (string)server.GetExtenderCellValue("_gametype");
              bool isTeamGame = gameType != "BL";
              var strSteamIds = (server.GetRule("p1073741829") ?? "") + (server.GetRule("p1073741830") ?? "") + (server.GetRule("p1073741831") ?? "");
              var strSkill = server.GetRule("p1073741837") ?? "";
              var strRank = server.GetRule("p1073741838") ?? "";
              int teamSepIdx = strNames.IndexOf(';');
              var names = strNames.Split(',', ';');
              var steamIds = strSteamIds.Split(',', ';');
              var skills = strSkill.Split(',',';');
              var ranks = strRank.Split(',', ';');
              int i = 0;
              foreach (var name in names)
              {
            var info = new ToxikkPlayerInfo();
            info.Team = !isTeamGame ? "Player" : teamSepIdx < 0 || strNames.IndexOf(name) < teamSepIdx ? "Red" : "Blue";
            if (i < steamIds.Length)
              info.SteamId = steamIds[i];

            decimal sc;
            if (i < skills.Length && decimal.TryParse(skills[i], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out sc))
              info.SkillClass = sc;
            int rank;
            if (i < ranks.Length && int.TryParse(ranks[i], out rank))
              info.Rank = rank;
            this.playerInfos.Add(name, info);
            ++i;
              }
        }
예제 #15
0
        public override object GetServerCellValue(ServerRow row, string fieldName)
        {
            switch (fieldName)
            {
            case "_skillclass":
                return(row.GetRule(ToxikkSkillInfo.MinSkillClass) + "-" + row.GetRule(ToxikkSkillInfo.MaxSkillClass));

            //return new ToxikkSkillInfo(row, this);
            case "_best":
                return(Math.Round(this.GetBestPlayerSC(row), 1, MidpointRounding.AwayFromZero));

            case NewOfficial:
            {
                var ver = row.GetRule(GameVersion);
                if (ver != null && CompareVersion(ver, "1.1.71") > 0)
                {
                    return(row.GetRule(NewOfficial) == "1");
                }
                return(row.GetRule(OldOfficialNewRanked) == "1");
            }

            case OldOfficialNewRanked:
            {
                var ver = row.GetRule(GameVersion);
                if (ver == null || CompareVersion(ver, "1.1.71") <= 0)
                {
                    return(null);
                }
                var val = row.GetRule(fieldName);
                return(val == null ? (object)null : val == "1");
            }

            case ModdingLevel:
                var level = row.GetRule(ModdingLevel);
                return(level == "0" ? "-" : level == "1" ? "S" : level == "2" ? "S+C" : "");

            case "_gametype":
            {
                var gt = row.ServerInfo.Extra.Keywords;
                return(gt == null ? null :
                       gt == "CRZEntryGame" ? "Menu" :
                       gt == "CRZBloodLust" ? "BL" :
                       gt == "CRZTeamGame" ? "SA" :
                       gt == "CRZCellCapture" ? "CC" :
                       gt == "CRZAreaDomination" ? "AD" :
                       gt == "CRZTimeTrial" ? "TT" :
                       gt == "CRZArchRivals" ? "AR" :
                       gt == "CRZSquadSurvival" ? "SS" :
                       gt == "InfekktedGame" ? "Inf" :
                       gt == "TAGame" ? "TA" :
                       gt == "TTGame" ? "TR" :
                       gt == "D2DGame" ? "2D" :
                       gt == "STBGame" ? "SB" :
                       gt == "Comp2v2" ? "2v2" :
                       gt == "Comp4v4" ? "4v4" :
                       gt);
            }

            case Mutators:
                var mods = (row.GetRule(fieldName) ?? "").ToLower();
                var buff = new StringBuilder();
                foreach (var mod in mods.Split('\x1c'))
                {
                    if (mod.Length == 0)
                    {
                        continue;
                    }
                    if (buff.Length > 0)
                    {
                        buff.Append(", ");
                    }
                    foreach (var word in mod.Split(' '))
                    {
                        buff.Append(char.ToUpper(word[0])).Append(word.Substring(1));
                    }
                }
                return(buff.ToString());
            }
            return(base.GetServerCellValue(row, fieldName));
        }
예제 #16
0
 /// <summary>
 /// Gets a value for a game specific column.
 /// Derived classes can put game specific logic here for more complex value calculations.
 /// The default implementation just looks up the given fieldName in the server's Rules collection.
 /// </summary>
 /// <param name="row">ServerRow object with all the data known about the server</param>
 /// <param name="fieldName">FieldName of the GridColumn that was added in <see cref="CustomizeServerGridColumns"/></param>
 public virtual object GetServerCellValue(ServerRow row, string fieldName)
 {
     return(row.GetRule(fieldName));
 }
예제 #17
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;
 }
예제 #18
0
        public override object GetServerCellValue(ServerRow row, string fieldName)
        {
            switch (fieldName)
            {
            case "g_factoryTitle":
            {
                var factory = row.GetRule("g_factoryTitle");
                return(string.IsNullOrEmpty(factory) ? row.ServerInfo?.Description : factory);
            }

            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");
                var    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 "_teamsize":
            {
                int ts;
                int.TryParse(row.GetRule("teamsize") ?? "0", out ts);
                return(ts == 0 ? null : (object)ts);
            }

            case "_skill":
            {
                QlStatsSkillInfo skill;
                if (!this.skillInfo.TryGetValue(row.ServerInfo.Address, out skill))
                {
                    return(null);
                }
                return("" + (skill.max + 50) / 100 + "/" + (skill.avg + 50) / 100 + "/" + (skill.min + 50) / 100);
            }

            case "_score":
            {
                var state = row.GetRule("g_gameState");
                if (state == "PRE_GAME")
                {
                    return(null);
                }
                var red = row.GetRule("g_redScore");
                var blue = row.GetRule("g_blueScore");
                int ired, iblue;
                if (int.TryParse(red, out ired) && int.TryParse(blue, out iblue) && iblue > ired)
                {
                    return("" + iblue + ":" + ired);
                }
                return("" + red + ":" + blue);
            }

            case "_time":
            {
                var time = row.GetRule("g_levelStartTime");
                if (time == null)
                {
                    return(null);
                }
                int itime;
                if (!int.TryParse(time, out itime))
                {
                    return(null);
                }
                var dt   = new DateTime(1970, 1, 1).AddSeconds(itime);
                var span = DateTime.UtcNow - dt;
                var str  = span.Minutes.ToString("d2") + ":" + span.Seconds.ToString("d2");
                if (span.TotalHours >= 1)
                {
                    str = span.Hours.ToString("d") + "h " + str;
                }
                if (span.TotalDays >= 1)
                {
                    str = ((int)span.TotalDays) + "d " + str;
                }
                return(str);
            }

            case "g_instaGib":
                return(row.GetRule(fieldName) == "1");

            case "g_loadout":
                return(row.GetRule(fieldName) == "1");

            case "g_itemTimers":
                return(row.GetRule(fieldName) == "1");
            }
            return(base.GetServerCellValue(row, fieldName));
        }
예제 #19
0
 /// <summary>
 /// Gets a value for a game specific column.
 /// Derived classes can put game specific logic here for more complex value calculations.
 /// The default implementation just looks up the given fieldName in the row's Rules collection.
 /// </summary>
 /// <param name="row">ServerRow object with all the data known about the server</param>
 /// <param name="fieldName">FieldName of the GridColumn that was added with CustomizeGridColumns</param>
 public virtual object GetServerCellValue(ServerRow row, string fieldName)
 {
     return row.GetRule(fieldName);
 }