public StatTracker() { m_eventLog = new List<EventLog>(); m_playerCache = new Dictionary<string, Player>(); m_itemCache = new Dictionary<string, string>(); m_currentEvent = new EventLog(); m_player = new Player(); m_sessionStats = new SessionStats(); m_userID = ""; m_sessionStarted = false; m_lastEventFound = false; m_initialized = false; m_initializing = false; m_countEvents = false; m_preparingSession = false; m_activeSeconds = 0; m_currentEvent.Initialize(); }
void UpdateEventLog(bool getName = false) { // Update the username displayed. if (getName) { GeckoElement title = (GeckoElement)m_browser.Document.GetElementById("title"); System.IO.TextReader nameReader = new System.IO.StringReader(title.InnerHtml); // Parse HTML by loading the text stream. HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument(); html.Load(nameReader); HtmlNode node = html.DocumentNode.SelectSingleNode(".//a"); this.playerNameLabel.Text = node.InnerText; this.playerNameLabel.Visible = true; m_username = node.InnerText; // Determine faction. Faction is stored as class name under logo. GeckoElement faction = (GeckoElement)m_browser.Document.GetElementById("factionLogo"); if (faction.ClassName == "faction_nc") m_userFaction = "NC"; else if (faction.ClassName == "faction_tr") m_userFaction = "TR"; else if (faction.ClassName == "faction_vs") m_userFaction = "VS"; else m_userFaction = "Unknown"; SaveUserName(); } // Get killboard table. GeckoElement collection = (GeckoElement)m_browser.Document.GetElementById("timelineTable"); if (collection == null) return; // Load formatted html with javascript results into reader stream. System.IO.TextReader reader = new System.IO.StringReader(collection.InnerHtml); // Parse HTML by loading the text stream. HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument(); htmlDoc.Load(reader); // Rows HtmlNodeCollection rows = htmlDoc.DocumentNode.SelectNodes(".//tr"); for (int i = 0; i < rows.Count; i++) { // Initialize new event. EventLog newEvent = new EventLog(); newEvent.Initialize(); // Columns HtmlNodeCollection cols = rows[i].SelectNodes(".//td"); // Timestamp, event, location, method. newEvent.timeStamp = cols[0].InnerText; newEvent.userName = cols[1].InnerText; newEvent.location = cols[2].InnerText; newEvent.method = cols[3].InnerText; // Determine faction from cols[1] inner html. if (cols[1].InnerHtml.Contains("faction nc")) newEvent.faction = "NC"; else if (cols[1].InnerHtml.Contains("faction tr")) newEvent.faction = "TR"; else if (cols[1].InnerHtml.Contains("faction vs")) newEvent.faction = "VS"; else newEvent.faction = "Unknown"; // Extract additional information. // Check for death. int indexStart = newEvent.userName.IndexOf("KILLED BY"); if (indexStart != -1) { // Remove KILLED BY and all white space. newEvent.userName = newEvent.userName.Remove(indexStart); newEvent.death = true; } newEvent.userName = RemoveWhiteSurroundingSpace(newEvent.userName); // Check for headshot. indexStart = newEvent.method.IndexOf("Headshot"); if (indexStart != -1) { // Remove KILLED BY and all white space. newEvent.method = newEvent.method.Remove(indexStart); newEvent.headshot = true; } newEvent.method = RemoveWhiteSurroundingSpace(newEvent.method); // Check for suicide. if (newEvent.userName == m_username || newEvent.method == "Suicide") { newEvent.death = true; newEvent.suicide = true; } // Check if the new event being added is the latest event. A full check needs to be done // if the current event doesn't match. Rarely the site may first report the items in the wrong order. if (newEvent == m_currentEvent || m_eventLog.Contains(newEvent)) break; // Determine the order in which to add the event. if (m_sessionStarted) { if (i < m_eventLog.Count) m_eventLog.Insert(i, newEvent); else m_eventLog.Add(newEvent); } else m_eventLog.Add(newEvent); // Add session weapon stats unless this event was a death or team kill. AddSessionWeapon(newEvent); } if (m_eventLog.Count > 0) { m_currentEvent = m_eventLog[0]; // Update killboard. this.eventLogGridView.Rows.Clear(); this.eventLogGridView.Rows.Add(m_eventLog.Count); int i = 0; foreach (EventLog eventlog in m_eventLog) { string eventName = eventlog.userName; this.eventLogGridView.Rows[i].Cells[0].Value = eventName; this.eventLogGridView.Rows[i].Cells[1].Value = eventlog.method; this.eventLogGridView.Rows[i].Cells[1].Style.ForeColor = Color.Beige; //this.eventLogGridView.Rows[i].Cells[2].Value = eventlog.headshot; if (eventlog.headshot) ((DataGridViewImageCell)eventLogGridView.Rows[i].Cells[2]).Value = Properties.Resources.hsImage; // Set row color depending on kill or death. for (int j = 0; j < this.eventLogGridView.Rows[i].Cells.Count; j++) { if (eventlog.death || eventlog.suicide) // Death. this.eventLogGridView.Rows[i].Cells[j].Style.BackColor = Color.Red; else if(eventlog.faction == m_userFaction) // Friendly kill. this.eventLogGridView.Rows[i].Cells[j].Style.BackColor = Color.Orange; else // Enemy kill. this.eventLogGridView.Rows[i].Cells[j].Style.BackColor = Color.Green; } i++; } this.eventLogGridView.ClearSelection(); UpdateEventTextFields(); UpdateWeaponTextFields(m_sessionWeapons, this.sessionWeaponsGridView); } m_lastEventFound = true; m_updatingEvents = false; }
void AddSessionWeapon(EventLog newEvent) { Weapon newWeapon = new Weapon(); Weapon oldWeapon = new Weapon(); oldWeapon.Initialize(); newWeapon.Initialize(); newWeapon.name = newEvent.method; newWeapon.kills += newEvent.IsKill() ? 1 : 0; newWeapon.headShots += newEvent.headshot ? 1 : 0; // Add to total deaths. if (m_sessionStarted) { if (!newEvent.IsKill()) { UpdateOverallStats(0, 0, 1); } // Update overall stats. Should only be called once overall stats have been set initially. // *Additionally it will not update a weapon not found in the All Weapons section. else { // * Testing with always updating stats regardless of if weapon was used previously. //if (m_weaponsUpdated && IsWeaponInAllWeapons(newWeapon.name)) //{ // Do not give kills or headshots for team kills. if(newEvent.faction != m_userFaction) UpdateOverallStats(newWeapon.kills, newWeapon.headShots, 0); //} } } // Add session weapon stats unless this event was a death or team kill. if(!newEvent.death && newEvent.faction != m_userFaction) AddSessionWeapon(newWeapon, oldWeapon); }
public GUIMain() { InitializeComponent(); // Load version. this.versionLabel.Text = PROGRAM_TITLE + " V " + VERSION_NUM; m_highColor = Color.FromArgb(0, 192, 0); m_lowColor = Color.Red; m_eventLog = new List<EventLog>(); m_weapons = new Dictionary<string, Weapon>(); m_sessionWeapons = new Dictionary<string, Weapon>(); m_sesStartWeapons = new Dictionary<string, Weapon>(); m_browser = new GeckoWebBrowser(); m_currentEvent = new EventLog(); m_sessionStarted = false; m_lastEventFound = false; m_initialized = false; m_pageLoaded = false; m_weaponsUpdated = false; m_dragging = false; m_resizing = false; m_totalHS = 0; m_totalKills = 0.0f; m_totalDeaths = 0.0f; m_totalDeathsWithRevives = 0.0f; m_activeSeconds = 0; m_timeout = 0; m_sessionStartHSR = 0.0f; m_sessionStartKDR = 0.0f; m_username = ""; m_userID = ""; m_userFaction = ""; // Prevent X images showing up. ((DataGridViewImageColumn)this.eventLogGridView.Columns[2]).DefaultCellStyle.NullValue = null; // Handle mouse movement and resizing on borderless window. this.resizePanelLR.MouseDown += OnMouseDownResize; this.resizePanelLR.MouseMove += OnMouseMove; this.resizePanelLR.MouseUp += OnMouseUp; MouseMove += OnMouseMove; MouseDown += OnMouseDown; MouseUp += OnMouseUp; foreach (Control ctrl in this.Controls) { if (ctrl.GetType() == typeof(Label)) { ctrl.MouseMove += OnMouseMove; ctrl.MouseDown += OnMouseDown; ctrl.MouseUp += OnMouseUp; } } this.menuStrip1.MouseMove += OnMouseMove; this.menuStrip1.MouseDown += OnMouseDown; this.menuStrip1.MouseUp += OnMouseUp; this.panel1.MouseMove += OnMouseMove; this.panel1.MouseDown += OnMouseDown; this.panel1.MouseUp += OnMouseUp; foreach (Control ctrl in this.panel1.Controls) { if (ctrl.GetType() == typeof(Label)) { ctrl.MouseMove += OnMouseMove; ctrl.MouseDown += OnMouseDown; ctrl.MouseUp += OnMouseUp; } } this.panel2.MouseMove += OnMouseMove; this.panel2.MouseDown += OnMouseDown; this.panel2.MouseUp += OnMouseUp; foreach (Control ctrl in this.panel2.Controls) { if (ctrl.GetType() == typeof(Label)) { ctrl.MouseMove += OnMouseMove; ctrl.MouseDown += OnMouseDown; ctrl.MouseUp += OnMouseUp; } } m_currentEvent.Initialize(); this.Controls.Add(m_browser); // Handler for when page load completes. m_browser.DocumentCompleted += new EventHandler(browser_DocumentCompleted); }
async Task AddSessionWeapon(EventLog newEvent) { Weapon newWeapon = new Weapon(); Weapon oldWeapon = new Weapon(); oldWeapon.Initialize(); newWeapon.Initialize(); if (newEvent.isVehicle) { newWeapon.id = "0"; newWeapon.vehicleId = newEvent.methodID; } else newWeapon.id = newEvent.methodID; newWeapon.name = await GetItemName(GetBestWeaponID(newWeapon)); newWeapon.kills += newEvent.IsKill() ? 1 : 0; newWeapon.headShots += newEvent.headshot ? 1 : 0; // Add to total deaths. if (m_sessionStarted || m_countEvents) { if (!newEvent.IsKill()) { UpdateOverallStats(0, 0, 1); } // Update overall stats. Should only be called once overall stats have been set initially. else { // Do not give kills or headshots for team kills. // TODO: If you kill someone that is so brand new that even their ID does not come through, // the defender will be null. So if the defender is null then a kill is currently counted. However, // the defender might be a team mate. The only fix I know of is to keep track of this and check it // occasionally and reverse the kill once the name is resolved and same faction is discovered. if (newEvent.defender == null || (newEvent.defender != null && newEvent.defender.faction != m_player.faction)) UpdateOverallStats(newWeapon.kills, newWeapon.headShots, 0); } } // Add session weapon stats unless this event was a death or team kill. if (!newEvent.death && (newEvent.defender == null || (newEvent.defender != null && newEvent.defender.faction != m_player.faction))) await AddSessionWeapon(newWeapon, oldWeapon); }
public async Task<bool> GetEventStats(int numEvents = 50) { string result = await GetAsyncRequest("characters_event/?character_id=" + m_userID + "&c:limit=" + numEvents + "&type=KILL,DEATH"); Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(result); if (jObject == null || !jObject.HasValues) return false; Newtonsoft.Json.Linq.JToken jToken = jObject["characters_event_list"]; if (jToken == null || !jToken.HasValues) return false; // Create a list of each json object. List<eventJson> jsonEvents = new List<eventJson>(); jsonEvents = Newtonsoft.Json.JsonConvert.DeserializeObject<List<eventJson>>(jToken.ToString()); int i = 0; // Convert the json object into an event with IDs resolved. foreach (eventJson jsonEvent in jsonEvents) { // Initialize new event. EventLog newEvent = new EventLog(); newEvent.Initialize(); Player attacker = await CreatePlayer(jsonEvent.attacker_character_id); Player defender = await CreatePlayer(jsonEvent.character_id); // Weapon IDs take priority over vehicle IDs. Weapon IDs such as breaker rocket pods // also show up with vehicle IDs like Reavers. A Reaver should only count if no // other weapon was used. if (jsonEvent.attacker_vehicle_id != "0" && jsonEvent.attacker_weapon_id == "0") { newEvent.methodID = jsonEvent.attacker_vehicle_id; newEvent.method = await GetVehicleName(jsonEvent.attacker_vehicle_id); newEvent.isVehicle = true; } else { newEvent.methodID = jsonEvent.attacker_weapon_id; newEvent.method = await GetItemName(jsonEvent.attacker_weapon_id); } newEvent.headshot = Int32.Parse(jsonEvent.is_headshot) == 1 ? true : false; newEvent.timeStamp = jsonEvent.timestamp; newEvent.attacker = attacker; newEvent.defender = defender; newEvent.death = defender == m_player; // Check for suicide. if ((attacker == m_player && defender == m_player)) { newEvent.death = true; newEvent.suicide = true; newEvent.method = "Suicide"; newEvent.opponent = m_player; } // Determine the best option for new information. if (attacker != null && attacker != m_player) newEvent.opponent = attacker; if (defender != null && defender != m_player) newEvent.opponent = defender; // Check if the new event being added is the latest event. A full check needs to be done // if the current event doesn't match. Rarely the site may first report the items in the wrong order. if (newEvent == m_currentEvent) break; // Don't add the same event. The API can sometimes report it twice. if (m_eventLog.Contains(newEvent)) continue; // If an iteration has gone through then new information has been gathered. m_hasEventUpdated = true; // Determine the order in which to add the event. if (m_sessionStarted) { if (i < m_eventLog.Count) m_eventLog.Insert(i, newEvent); else m_eventLog.Add(newEvent); } else m_eventLog.Add(newEvent); if (!m_preparingSession) { // Add session weapon stats unless this event was a death or team kill. if(i < numEvents - 1) await AddSessionWeapon(newEvent); } i++; } // Display the killboard. // Only update the fields if a change in events occurred. if (i > 0) { m_currentEvent = m_eventLog[0]; m_lastEventFound = true; } // Update loaded players' online status. await CheckOnlineStatus(); return true; }
private static bool MyEquals(EventLog e1, EventLog e2) { return (e1.headshot == e2.headshot && e1.location == e2.location && e1.method == e2.method && e1.suicide == e2.suicide && e1.timeStamp == e2.timeStamp && ((e1.attacker == null && e2.attacker == null) || (e1.attacker != null && e2.attacker != null && e1.attacker.fullName == e2.attacker.fullName)) && ((e1.defender == null && e2.defender == null) || (e1.defender != null && e2.defender != null && e1.defender.fullName == e2.defender.fullName))); }