private static Stack <CodServerLogLine> FindAllValidLogLines(List <string> lines, ref double lastTimeStampRead) { var parsedLines = new Stack <CodServerLogLine>(); lines.Reverse(); foreach (var line in lines) { Logging.WriteLog(line); var parsedLine = CodServerLogLine.ParseLine(line); if (parsedLine == null) { Logging.WriteLog("Skipping null line"); continue; } if (parsedLine.TimeStamp == 0) { // time restarted lastTimeStampRead = 0; } parsedLines.Push(parsedLine); if (parsedLine.LineType == LogLineType.Init) { break; } if (parsedLine.LineType == LogLineType.Shutdown) { //we ended a round, but haven't started a new one... //just exit the log handler for now. Logging.WriteLog("Skipping parsing logs because we reached the end of a round"); return(null); } } return(parsedLines); }
private static void EnforceRules(CodServerLogLine line) { var violations = RulesValidator.CheckDamageAndKillsForViolations(line.Weapon); if (violations == ViolationType.None) { Logging.WriteLog("No violations for {0}", line.PlayerName); return; //good doggy! } CodPlayer player; lock (currentPlayers) { if (!currentPlayers.TryGetValue(line.PlayerId, out player)) { player = CreatePlayer(line.PlayerName, line.PlayerId); currentPlayers[line.PlayerId] = player; } } bool kickPlayer = false; if (violations == ViolationType.Knife) { if (line.IsMelee) { lock (player.Warnings) { if (!player.Warnings.Contains(Warning.Knifing)) { //warn the player Logging.WriteLog(String.Format("Sending warning to {0} for knifing violation.", player.FullName)); rcon.Say(String.Format(Strings.WarningMessage, Strings.KnifeUsage, CodServerLogLine.RulesTrigger), player.Id); player.Warnings.Add(Warning.Knifing); } else { kickPlayer = true; } } } } else { lock (player.Warnings) { if (!player.Warnings.Contains(Warning.Illegal_Weapons)) { Logging.WriteLog(String.Format("Sending warning to {0} for weapon violation: {1}", player.FullName, line.Weapon)); //warn the player rcon.Say(String.Format(Strings.WarningMessage, Strings.FollowRules, CodServerLogLine.RulesTrigger), player.Id); player.Warnings.Add(Warning.Illegal_Weapons); } else { kickPlayer = true; } } } if (kickPlayer) { Logging.WriteLog(String.Format("Kicking player {0}. For {1}", player.FullName, line.Weapon)); //boot this douche, but first message the entire server rcon.Say(String.Format(Strings.Kicked, player.FullName)); Thread.Sleep(1000); //badbad rcon.ClientKick(player.Id); } }
internal static CodServerLogLine ParseLine(string line) { CodServerLogLine csl = new CodServerLogLine(); var m = regex.Match(line); if (!m.Success) { return(null); } double d; if (!Double.TryParse(String.Concat(m.Groups[1].Value, ".", m.Groups[2].Value), out d)) { // couldn't parse the time stamp return(null); } csl.TimeStamp = d; var data = m.Groups[3].Value.Split(';'); //handle special cases for broken lines, init and shutdown if (data.Count() == 1) { if (data[0].Contains("InitGame:")) { csl.LineType = LogLineType.Init; return(csl); } else if (data[0].Contains("ShutdownGame:")) { csl.LineType = LogLineType.Shutdown; return(csl); } return(null); } var command = data[0]; switch (command) { case "J": if (data.Length < 4) { csl.LineType = LogLineType.Blank; break; } csl.LineType = LogLineType.Join; csl.PlayerId = data[2].Trim(); csl.PlayerName = data[3].Trim(); break; case "Q": if (data.Length < 4) { csl.LineType = LogLineType.Blank; break; } csl.LineType = LogLineType.Quit; csl.PlayerId = data[2].Trim(); csl.PlayerName = data[3].Trim(); break; case "say": if (data.Length < 5) { csl.LineType = LogLineType.Blank; break; } csl.LineType = LogLineType.Say; csl.PlayerId = data[2].Trim(); csl.PlayerName = data[3].Trim(); if (data.Length > 4 && data[4].Contains(RulesTrigger)) { csl.RulesRequest = true; } break; case "D": case "K": if (data.Length < 12) { csl.LineType = LogLineType.Blank; //broken line break; } csl.LineType = LogLineType.Kill_Damage; csl.PlayerId = data[6].Trim(); csl.PlayerName = data[8].Trim(); csl.Weapon = data[9].Trim(); if (data[11].Contains("MOD_MELEE")) { csl.IsMelee = true; } break; default: if (data[0].Contains("InitGame:")) { csl.LineType = LogLineType.Init; } else if (data[0].Contains("ShutdownGame:")) { csl.LineType = LogLineType.Shutdown; } else { csl.LineType = LogLineType.Blank; } break; } return(csl); }
internal static CodServerLogLine ParseLine(string line) { CodServerLogLine csl = new CodServerLogLine(); var m = regex.Match(line); if (!m.Success) { return null; } double d; if (!Double.TryParse(String.Concat(m.Groups[1].Value, ".", m.Groups[2].Value), out d)) { // couldn't parse the time stamp return null; } csl.TimeStamp = d; var data = m.Groups[3].Value.Split(';'); //handle special cases for broken lines, init and shutdown if (data.Count() == 1) { if (data[0].Contains("InitGame:")) { csl.LineType = LogLineType.Init; return csl; } else if (data[0].Contains("ShutdownGame:")) { csl.LineType = LogLineType.Shutdown; return csl; } return null; } var command = data[0]; switch (command) { case "J": if (data.Length < 4) { csl.LineType = LogLineType.Blank; break; } csl.LineType = LogLineType.Join; csl.PlayerId = data[2].Trim(); csl.PlayerName = data[3].Trim(); break; case "Q": if (data.Length < 4) { csl.LineType = LogLineType.Blank; break; } csl.LineType = LogLineType.Quit; csl.PlayerId = data[2].Trim(); csl.PlayerName = data[3].Trim(); break; case "say": if (data.Length < 5) { csl.LineType = LogLineType.Blank; break; } csl.LineType = LogLineType.Say; csl.PlayerId = data[2].Trim(); csl.PlayerName = data[3].Trim(); if (data.Length > 4 && data[4].Contains(RulesTrigger)) { csl.RulesRequest = true; } break; case "D": case "K": if (data.Length < 12) { csl.LineType = LogLineType.Blank; //broken line break; } csl.LineType = LogLineType.Kill_Damage; csl.PlayerId = data[6].Trim(); csl.PlayerName = data[8].Trim(); csl.Weapon = data[9].Trim(); if(data[11].Contains("MOD_MELEE")) { csl.IsMelee = true; } break; default: if (data[0].Contains("InitGame:")) { csl.LineType = LogLineType.Init; } else if (data[0].Contains("ShutdownGame:")) { csl.LineType = LogLineType.Shutdown; } else { csl.LineType = LogLineType.Blank; } break; } return csl; }