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; }
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 != "")); }
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); }
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); }
public override int?GetMaxPlayers(ServerRow row) { var val = row.GetRule("NumPublicConnections"); if (val != null) { return(int.Parse(val)); } return(base.GetMaxPlayers(row)); }
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); }
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); }
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); }
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)); }
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); }
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(); }
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); }
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); }
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; } }
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)); }
/// <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)); }
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; }
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)); }
/// <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); }