internal static void ReadRoleRatings(Bitmap frame) { Rectangle tankRect = Rectangles.TankCheck; Rectangle damageRect = Rectangles.DamageCheck; Rectangle supportRect = Rectangles.SupportCheck; Rectangle tankRatingRect = Rectangles.TankRating; Rectangle damageRatingRect = Rectangles.DamageRating; Rectangle supportRatingRect = Rectangles.SupportRating; bool tankCheck = BitmapFunctions.BitmapIsCertainColor(BitmapFunctions.CropImage(frame, tankRect), 255, 255, 255); bool damageCheck = BitmapFunctions.BitmapIsCertainColor(BitmapFunctions.CropImage(frame, damageRect), 255, 255, 255); bool supportCheck = BitmapFunctions.BitmapIsCertainColor(BitmapFunctions.CropImage(frame, supportRect), 255, 255, 255); int tankRating = 0; int damageRating = 0; int supportRating = 0; string debugString = ""; if (!tankCheck && !damageCheck && !supportCheck) { tankRect.X -= 226; damageRect.X -= 226; supportRect.X -= 226; tankRatingRect.X -= 226; damageRatingRect.X -= 226; supportRatingRect.X -= 226; tankCheck = BitmapFunctions.BitmapIsCertainColor(BitmapFunctions.CropImage(frame, tankRect), 255, 255, 255); damageCheck = BitmapFunctions.BitmapIsCertainColor(BitmapFunctions.CropImage(frame, damageRect), 255, 255, 255); supportCheck = BitmapFunctions.BitmapIsCertainColor(BitmapFunctions.CropImage(frame, supportRect), 255, 255, 255); } if (tankCheck) { string tankRatingText = BitmapFunctions.ProcessFrame(frame, tankRatingRect, true, 110, NetworkEnum.Ratings, true); if (tankRatingText.Length > 4) { tankRatingText = tankRatingText.Substring(tankRatingText.Length - 4); } else if (tankRatingText.Length < 4) { tankCheck = false; } if (tankCheck && int.TryParse(tankRatingText, out tankRating)) { debugString += $" Tank: {tankRatingText}"; } } if (damageCheck) { string damageRatingText = BitmapFunctions.ProcessFrame(frame, damageRatingRect, true, 110, NetworkEnum.Ratings, true); if (damageRatingText.Length > 4) { damageRatingText = damageRatingText.Substring(damageRatingText.Length - 4); } else if (damageRatingText.Length < 4) { damageCheck = false; } if (damageCheck && int.TryParse(damageRatingText, out damageRating)) { debugString += $" Damage: {damageRatingText}"; } } if (supportCheck) { string supportRatingText = BitmapFunctions.ProcessFrame(frame, supportRatingRect, true, 110, NetworkEnum.Ratings, true); if (supportRatingText.Length > 4) { supportRatingText = supportRatingText.Substring(supportRatingText.Length - 4); } else if (supportRatingText.Length < 4) { supportCheck = false; } if (supportCheck && int.TryParse(supportRatingText, out supportRating)) { debugString += $" Support: {supportRatingText}"; } } if ((tankCheck || damageCheck || supportCheck) && (tankCheck && AppData.gameData.currentRatings.tank != tankRating || damageCheck && AppData.gameData.currentRatings.damage != damageRating || supportCheck && AppData.gameData.currentRatings.support != supportRating || AppData.gameData.state >= State.Record)) { if (tankCheck) { AppData.gameData.currentRatings.tank = tankRating; if (AppData.settings.outputToTextFiles) { try { File.WriteAllText("tank.txt", tankRating.ToString()); Functions.DebugMessage($"Updated tank.txt with '{tankRating}'"); } catch (Exception e) { Functions.DebugMessage($"Failed to update tank.txt : {e.Message}"); } } } if (damageCheck) { AppData.gameData.currentRatings.damage = damageRating; if (AppData.settings.outputToTextFiles) { try { File.WriteAllText("damage.txt", damageRating.ToString()); Functions.DebugMessage($"Updated damage.txt with '{damageRating}'"); } catch (Exception e) { Functions.DebugMessage($"Failed to update damage.txt : {e.Message}"); } } } if (supportCheck) { AppData.gameData.currentRatings.support = supportRating; if (AppData.settings.outputToTextFiles) { try { File.WriteAllText("support.txt", supportRating.ToString()); Functions.DebugMessage($"Updated support.txt with '{supportRating}'"); } catch (Exception e) { Functions.DebugMessage($"Failed to update support.txt : {e.Message}"); } } } AppData.successSound.Play(); Functions.DebugMessage($"Recognized rating:{debugString}"); if (AppData.gameData.state >= State.Record) { AppData.gameData.timer.Stop(); Server.CheckGameUpload(); AppData.gameData = new GameData(AppData.gameData.currentRatings); } else { ScreenCaptureHandler.trayMenu.ChangeTray("Ready to record, enter a competitive game to begin", Resources.Icon_Active); } } }
internal static void ScreenCapture() { AppData.statsTimer.Restart(); try { desktopDuplicator = new DesktopDuplicator(0); } catch (Exception e) { Functions.DebugMessage("Could not initialize desktopDuplication API - shutting down:" + e); Environment.Exit(0); } while (true) { if (!captureScreen) { Thread.Sleep(1000); continue; } if (!AppData.overwatchRunning && !debug) { if (Functions.IsProcessOpen("Overwatch")) { if (AppData.gameData.currentRatings.AverageRating() > 0) { trayMenu.ChangeTray("Ready to record, enter a competitive game to begin", Resources.Icon_Active); } else { trayMenu.ChangeTray("Visit play menu to update your skill rating", Resources.Icon_Wait); } AppData.overwatchRunning = true; } else { Server.AutoUpdater(); } } else { if (!Functions.IsProcessOpen("Overwatch") && !debug) { trayMenu.ChangeTray("Waiting for Overwatch, idle...", Resources.Icon); AppData.overwatchRunning = false; if (AppData.gameData.state == State.RoundComplete || AppData.gameData.state == State.Record || AppData.gameData.state == State.Finished || AppData.gameData.state == State.Upload ) { Server.CheckGameUpload(); AppData.gameData = new GameData(AppData.gameData.currentRatings); } } } if ((!AppData.overwatchRunning || AppData.gameData.state == State.Record && !Functions.ActiveWindowTitle().Equals("Overwatch")) && !debug) { Thread.Sleep(1000); continue; } else { Thread.Sleep(AppData.loopDelay); } DesktopFrame frame; try { frame = desktopDuplicator.GetLatestFrame(); } catch { desktopDuplicator.Reinitialize(); continue; } if (frame != null) { try { if (AppData.gameData.state != State.Ingame) { if (GameMethods.IsOnCompetitiveScreen(frame.DesktopImage) || true) { if (AppData.ratingsTimer.ElapsedMilliseconds >= 500) { GameMethods.ReadRoleRatings(frame.DesktopImage); } else { AppData.ratingsTimer.Start(); } } else { AppData.ratingsTimer.Reset(); } } if (AppData.gameData.state == State.Idle || AppData.gameData.state == State.Finished || AppData.gameData.state == State.Upload) { GameMethods.ReadCompetitiveGameEntered(frame.DesktopImage); } if (AppData.gameData.state == State.Ingame) { if (AppData.infoTimer.ElapsedMilliseconds > 5000) { AppData.gameData.timer.Reset(); AppData.infoTimer.Reset(); AppData.gameData.state = State.Idle; Functions.DebugMessage("Failed to find game"); } else if (AppData.infoTimer.ElapsedMilliseconds > 1500 || !AppData.gameData.map.Equals(string.Empty)) { if (AppData.gameData.map.Equals(string.Empty)) { GameMethods.ReadMap(frame.DesktopImage); } else { GameMethods.ReadTeamsSkillRating(frame.DesktopImage); if (AppData.gameData.playerListImage == null) { try { frame = desktopDuplicator.GetLatestFrame(); AppData.gameData.playerListImage = new Bitmap(BitmapFunctions.CropImage(frame.DesktopImage, Rectangles.PlayerListImage)); GameMethods.ReadPlayerNamesAndRank(frame.DesktopImage); } catch { } } AppData.loopDelay = 500; AppData.gameData.state = State.RoundComplete; AppData.gameData.timer.Start(); AppData.ratingsTimer.Reset(); AppData.statsTimer.Restart(); AppData.infoTimer.Restart(); trayMenu.ChangeTray("Recording... visit the main menu after the game", Resources.Icon_Record); } } } if (AppData.gameData.state == State.Record) { if (AppData.gameData.tabPressed && AppData.gameData.tabTimer.ElapsedMilliseconds > 250) { if (GameMethods.ReadHeroPlayed(frame.DesktopImage)) { GameMethods.ReadStats(frame.DesktopImage); } } GameMethods.ReadRoundCompleted(frame.DesktopImage); GameMethods.ReadMainMenu(frame.DesktopImage); GameMethods.ReadFinalScore(frame.DesktopImage); } if (AppData.gameData.state == State.RoundComplete) { if (AppData.gameData.tabPressed && AppData.gameData.tabTimer.ElapsedMilliseconds > 250) { GameMethods.ReadHeroPlayed(frame.DesktopImage); } else if (GameMethods.ReadRoundStarted(frame.DesktopImage) || AppData.infoTimer.Elapsed.TotalSeconds > 80) { Functions.DebugMessage("Waiting for doors to open..."); AppData.infoTimer.Restart(); AppData.gameData.state = State.RoundStart; } GameMethods.ReadMainMenu(frame.DesktopImage); } if (AppData.gameData.state == State.RoundStart) { if (AppData.infoTimer.Elapsed.TotalSeconds >= 40 || AppData.infoTimer.Elapsed.TotalSeconds >= 30 && AppData.gameData.IsKoth()) { AppData.gameData.gameTimer.Start(); AppData.gameData.heroTimer.Start(); if (AppData.gameData.heroesPlayed.Count > 0 && AppData.gameData.heroesPlayed[AppData.gameData.heroesPlayed.Count - 1].time == 0) { AppData.gameData.heroesPlayed[AppData.gameData.heroesPlayed.Count - 1].startTime = (int)AppData.gameData.gameTimer.Elapsed.TotalSeconds; } AppData.gameData.state = State.Record; int roundedSecs = AppData.gameData.gameTimer.Elapsed.TotalSeconds < 2000 ? (int)Math.Floor(AppData.gameData.gameTimer.Elapsed.TotalSeconds) : 0; Functions.DebugMessage($"Round started after {roundedSecs} seconds, goodluck!"); } else if (AppData.gameData.tabPressed && AppData.gameData.tabTimer.ElapsedMilliseconds > 250 /*Functions.GetAsyncKeyState(0x09) < 0*/) { GameMethods.ReadHeroPlayed(frame.DesktopImage); } } if (AppData.gameData.state == State.Finished && AppData.infoTimer.ElapsedMilliseconds >= 500) { GameMethods.ReadGameScore(frame.DesktopImage); } } catch (Exception e) { Functions.DebugMessage("Main Exception: " + e); Thread.Sleep(500); } } } }