public void loadSettingValueFromConfig(string key, string value) { switch (key) { case Config.keyActionBringGameToFront: setBringGameToFront(bool.Parse(value)); break; case Config.keyActionMustPlaySound: setMustPlaySound(bool.Parse(value)); break; case Config.keyActionSoundName: var soundEnum = Sound.getSoundsEnumFromSoundsEnumString(value); Dbg.assert(soundEnum != null); setSoundName((SoundsEnum)soundEnum); break; case Config.keyActionPlayLooped: setPlaySoundLooped(bool.Parse(value)); break; default: Dbg.onDebugError("Unknown action setting: " + key); break; } }
/// <summary> /// Get point coord and check its color if it fits /// </summary> private bool isGamePointRecognized(GamePoint gamePoint, string resolution, int horizontalOffset = 0, int verticalOffset = 0, PointColor color = PointColor.Default) { PointColor pointColor = gamePoint.getPointColor(); // Do we pass the color with the call and not during data definition? if (pointColor == PointColor.WillProvidLater) { // Make sure we have provided a real color Dbg.assert(color != PointColor.WillProvidLater && color != PointColor.Default && color != PointColor.Error); pointColor = color; } List <Point> alternatePoints = gamePoint.getAlternatePoint(resolution); // If 1 of any alternate points is recognized, then point of gfx object is recognized foreach (Point point in alternatePoints) { var pixelColor = ScreenCapture.getScreenShot().GetPixel(point.X + horizontalOffset, point.Y + verticalOffset); if (isPixelColorFitsGameColor(pixelColor, pointColor)) { return(true); } } return(false); }
/// <summary> /// Convert all digits to an int /// </summary> public static int getIntFromDigitSequence(List <DigitEnum> digits) { // Must have 5 digits for BP score Dbg.assert(digits.Count == 5); string sNumber = ""; for (int d = (int)DigitPosition.DigitPos0; d <= (int)DigitPosition.DigitPos4; d++) { Dbg.assertDigitEnumIsInRange(digits[d]); // Skip errors at the beginning, that means there is no digit // because the number is small, like " 7365" if (digits[d] != DigitEnum.Error) { sNumber = sNumber + (( int )digits[d]).ToString(); } } // Error recognizing? if (sNumber.Trim() == "") { return(INVALID_BP_AMOUNT); } return(int.Parse(sNumber)); }
/// <summary> /// Sounds.Notify2 => "Notify 2" /// </summary> public static string getSoundNameFromSound(SoundsEnum sound) { Dbg.assert(sound != SoundsEnum.None, "Wrong sound: " + sound.ToString()); Dbg.assert(soundsToString.ContainsKey(sound), "Wrong sound: " + sound.ToString()); return(soundsToString[sound]); }
/// <summary> /// Date format: dd.mm.yyyy /// </summary> public static DateTime parseDateFromDdMmYyyyString(string date) { if (date == null) { return(DateTime.MinValue); } date = date.Trim(); if (date == "") { return(DateTime.MinValue); } // Split by '.' var values = date.Split('.'); Dbg.assert(values.Length == 3, "Wrong date format: " + date); int day = int.Parse(values[0].Trim()); int month = int.Parse(values[1].Trim()); int year = int.Parse(values[2].Trim()); return(new DateTime(year, month, day)); // return DateTime.Now.Day + "." + DateTime.Now.Month + "." + DateTime.Now.Year; }
public bool recognize( ) { Dbg.assert(this is EndscoreBpDigitGfx == false, "This class is not supported by this method"); var gameResolution = ScreenCapture.getScreenshotResolutionAsString(); return(recognize(gameResolution)); }
public void setSurvivorIcon(int survivorIndex, EndgameSurvivorIcon survIcon) { Dbg.assert(playerIconList.Count > survivorIndex); Dbg.assert(survivorIndex >= 0, "Survivor index too low"); Dbg.assert(survivorIndex <= 3, "Survivor index too high"); this.playerIconList[survivorIndex] = survIcon; }
public bool recognize(PointColor color) { Dbg.assert(color != PointColor.WillProvidLater && color != PointColor.Error, "Wrong color provided"); var gameResolution = ScreenCapture.getScreenshotResolutionAsString(); return(recognize(gameResolution, 0, 0, false, color)); }
/// <summary> /// Add game to stats /// </summary> public static void addGameToStats(GameResult game, bool bSaveToDisk = true) { Dbg.assert(game != null); games.Add(game); // Save immediately if needed if (bSaveToDisk) { StatSaver.save(); } }
public static Action addAction(StateManager.State actionForState, string actionDescription) { Action action = new Action(actionDescription); action.forState = actionForState; Dbg.assert(!actions.ContainsKey(actionForState), "Action already registered: " + actionForState.ToString()); // Save action actions[actionForState] = action; return(action); }
public static void updateEndgameScoreboardState(bool bSuppressStateDebugCheck = false) { // Only makes sense in this state if (!bSuppressStateDebugCheck) { Debug.Assert(getState() == State.Endgame_ScoreBoard); } // Player we are playing as (killer or survivor index) var selectedPlayer = ScreenParser.recognizeScoreboardSelectedPlayer(bSuppressStateDebugCheck); // Failed to recognize selected player this time? Leave the old value, maybe it succeeded previously if (selectedPlayer != PlayerIndex.Error) { scoreboardGameResult.setSelectedPlayerIndex(selectedPlayer); } // Make sure game type is save correctly, it shouldn't change here Dbg.assert(scoreboardGameResult.getGameType() == getGameType()); // Recognize game result icons for all 4 survivors EndgameSurvivorIcon[] survivorGameResults = new EndgameSurvivorIcon[4]; for (int surv = 0; surv <= 3; surv++) { survivorGameResults[surv] = ScreenParser.recognizeEndgameScoreboardSurvIcon((PlayerIndex)surv); // When we mouse-over perk description, result icons gets covered and can't be recornized // So, if we have an error while recognizing it, leave the last value if (survivorGameResults[surv] != EndgameSurvivorIcon.Error) { scoreboardGameResult.setSurvivorIcon(surv, survivorGameResults[surv]); } } // Get Bloodpoints amounts for (int player = ( int )PlayerIndex.Survivor1; player <= ( int )PlayerIndex.Killer; player++) { int bpAmount = EndscoreBpDigitGfx.recognizePlayerBPNumber(( PlayerIndex )player); if (bpAmount != EndscoreBpDigitGfx.INVALID_BP_AMOUNT) { scoreboardGameResult.setBpAmount(( PlayerIndex )player, bpAmount); } } // Debug Log.log(scoreboardGameResult.iconsToString()); }
public static void load() { // Exit if no stats file if (!File.Exists(filePath)) { return; } Dbg.assert(Stats.getGames().Count == 0, "Trying to load stats while they are already loaded, " + "might lose loaded stats"); if (Stats.getGames().Count > 0) { return; } List <GameResult> games = new List <GameResult>(); GameResult game = null; using (StreamReader file = new StreamReader(filePath)) { while (!file.EndOfStream) { var line = file.ReadLine(); game = null; try { game = parseGameLine(line); } catch (Exception e) { Dbg.onDebugError("Error loading stats line: " + e.ToString()); } if (game != null) { games.Add(game); } } } Stats.setGames(games); bStatsLoaded = true; }
/// <summary> /// We can only be missing digits at the beginning (because the number is small), /// not in the center, or at the end. E.g. "33333" - valid, /// "33_33" - not valid, "3333_" - not valid /// </summary> public static bool isDigitSequenceNotInterrupting(List <DigitEnum> digits, PlayerIndex playerIndex) { Dbg.assertPlayerIndexIsInRangeAndNotInvalid(playerIndex); // Must have 5 digits for BP score Dbg.assert(digits.Count == 5); bool bSequenceStarted = false; DigitEnum firstDigit = DigitEnum.Error; DigitPosition firstDigitIndex = DigitPosition.Error; // From left to right - For all digits in list see if sequence interrupts for (int d = ( int )DigitPosition.DigitPos0; d <= (int)DigitPosition.DigitPos4; d++) { Dbg.assertDigitEnumIsInRange(digits[d]); // We previously found a valid digit, must be followed by digits until the end // If it's not then we have an error if (bSequenceStarted && digits[d] == DigitEnum.Error) { //Dbg.onError( "Wrong BP digit sequence at pos: " + d.ToString() + // " for player: " + playerIndex.ToString() ); return(false); } // Did we find the first valid digit? if (!bSequenceStarted && digits[d] != DigitEnum.Error) { firstDigit = digits[d]; firstDigitIndex = ( DigitPosition )d; bSequenceStarted = true; } } // We can only have '0' at the beginning if it's the last digit (usually on DC) if (firstDigit == DigitEnum.Digit0) { if (firstDigitIndex != DigitPosition.DigitPos4) { return(false); } } return(true); }
/// <summary> /// "Notify 2" => Sounds.Notify2 /// </summary> public static SoundsEnum getSoundFromSoundName(string sSoundName) { sSoundName = sSoundName.Trim(); Dbg.assert(soundsToString.ContainsValue(sSoundName)); foreach (var kvp in soundsToString) { if (kvp.Value == sSoundName) { return(kvp.Key); } } Dbg.onDebugError("Wrong sound name: " + sSoundName); return(SoundsEnum.None); }
/// <summary> /// Save to disk /// </summary> public static void save() { Dbg.assert(bStatsLoaded, "Trying to save stats without loading them first," + " might delete all stats this way"); if (!bStatsLoaded) { return; } //var comment = ";playerIndex(0-4)/s0_res/s1_res/s2_res/s3_res/k_res/pip?/duration/date/BP/killer_surv_name/"; var ver = "ver=1.0"; var result = ver + "\n\n"; using (StreamWriter file = new StreamWriter(filePath)) { foreach (var game in Stats.getGames()) { var gameResult = ""; try { gameResult = game.getStringForSaving(); } catch (Exception e) { Dbg.onDebugError("Error saving stats line: " + e.ToString()); } // Make more readable gameResult = gameResult.Replace(gameFieldsSeparator, " " + gameFieldsSeparator + " "); result = result + "\n" + gameResult; // write line by line, in case we get an error and lose some data file.WriteLine(gameResult); file.Flush(); } //file.Write( result ); } }
public static int getStatsOtherSurvivorAverageBP() { // Get my survivor games (solo and SWF), exclude games with DC during game load var myRankedSurvivorGames = getGames().Where(g => g.isMyGameRoleIsSurvivor() && g.isSoloOrSwfSurvivorGame() && !g.isThisGameCanceledBecauseOfDCWhileLoading()); int numPlayersWithValidBP = 0; int totalBP = 0; foreach (var g in myRankedSurvivorGames) { Dbg.assert(g.isMyGameRoleIsSurvivor()); for (int player = (int)PlayerIndex.Survivor1; player <= (int)PlayerIndex.Survivor4; player++) { // make sure it's not me. but some other survivor if (( PlayerIndex )player != g.getSelectedPlayerIndex()) { // make sure this survivor didn't DC, otherwise his BP will be 0 // Also make sure he is not still playing, otherwise his BP is not final if (g.isSurvivorKilledOrEscaped(player)) { // Only if have BP stored if (g.isBpAmountSet(( PlayerIndex )player)) { totalBP = totalBP + g.getBpAmount(( PlayerIndex )player); numPlayersWithValidBP++; } } } } } // Avoid division by 0 if (numPlayersWithValidBP == 0) { return(invalidIntValue); } // calc escape rate % int result = totalBP / numPlayersWithValidBP; return(result); }
/// <summary> /// Add results of the current game /// </summary> public static void addCurGameResult(GameResult curGameResult) { Dbg.assert(curGameResult != null); // Exit if we are not allowed to add new results if (!Form1.getInstance().isAddNewGameResultsEnabled()) { return; } // Set date of this game to today curGameResult.setDate(DateTime.Now); lastGameResult = curGameResult; Log.log("Cur game stats stored: " + curGameResult.ToString()); addGameToStats(curGameResult); Actions.onAddCurGameToResults(); }
public static void load() { // Exit if no stats file if (!File.Exists(filePath)) { return; } using (StreamReader file = new StreamReader(filePath)) { while (!file.EndOfStream) { var line = file.ReadLine(); line = line.Trim(); var v = line.Split(new string[] { Config.keyAndValueSeparatorForSaving }, StringSplitOptions.None); // Make sure we have both: field name and value if (v.Length != 2) { continue; } string fieldName = v[0].Trim(); string value = v[1].Trim(); // Make sure this is not a duplicate entry Dbg.assert(!settingValues.ContainsKey(fieldName)); //settingValues[ fieldName ] = value; // Get key and subkey var keyAndSubkey = fieldName.Split(new string[] { Config.keyAndSubkeySeparatorForSaving }, StringSplitOptions.None); Dbg.assert(keyAndSubkey.Length == 2); string mainKey = keyAndSubkey[0].Trim(); string subKey = keyAndSubkey[1].Trim(); if (mainKey == Config.keyPrefixGeneral) { parseGeneralSettingLine(subKey, value); } else { // This is a setting for an action parseSettingLineForAction(mainKey, subKey, value); } } } void parseGeneralSettingLine(string subKey, string setting) { subKey = subKey.Trim(); Config.setConfigValue(subKey, bool.Parse(setting)); } void parseSettingLineForAction(string mainKey, string subKey, string value) { string stateString = mainKey; var state = StateManager.getStateEnumFromStateEnumDescription(stateString); Dbg.assert(state != null); var action = Actions.getActions()[(StateManager.State)state]; action.loadSettingValueFromConfig(subKey, value); } }
public static void assertIndexIsWithinRange(int index, int lowestAcceptable, int higherstAcceptable) { Dbg.assert(index >= lowestAcceptable, "Index too low"); Dbg.assert(index <= higherstAcceptable, "Index too high"); }
private static GameResult parseGameLine(string line) { if (line.Trim() == "") { return(null); } // "g=..." var v = line.Split(new string[] { lineNameSeparator }, 2, StringSplitOptions.RemoveEmptyEntries); if (v.Length != 2) { return(null); } var lineType = v[0].Trim(); // Not a game stat line? if (lineType != lineGameStat) { return(null); } var lineFields = v[1].Trim(); var gameLineFields = lineFields.Split(new string[] { gameFieldsSeparator }, StringSplitOptions.RemoveEmptyEntries); PlayerIndex playerIndex = PlayerIndex.Error; EndgameSurvivorIcon surv1Result = EndgameSurvivorIcon.Error; EndgameSurvivorIcon surv2Result = EndgameSurvivorIcon.Error; EndgameSurvivorIcon surv3Result = EndgameSurvivorIcon.Error; EndgameSurvivorIcon surv4Result = EndgameSurvivorIcon.Error; DateTime gameDate = DateTime.MinValue; GameType gameType = GameType.Error; int[] bloodpoints = new int[5] { EndscoreBpDigitGfx.INVALID_BP_AMOUNT, EndscoreBpDigitGfx.INVALID_BP_AMOUNT, EndscoreBpDigitGfx.INVALID_BP_AMOUNT, EndscoreBpDigitGfx.INVALID_BP_AMOUNT, EndscoreBpDigitGfx.INVALID_BP_AMOUNT }; GameResult game = null; foreach (var gameField in gameLineFields) { var fieldNameAndValue = gameField.Split(new string[] { gameFieldValueSeparator }, 2, StringSplitOptions.None); Dbg.assert(fieldNameAndValue.Length == 2, "Wrong game value format"); var fieldName = fieldNameAndValue[0].Trim(); var fieldValue = fieldNameAndValue[1].Trim(); // Player index if (fieldName.Trim() == gameLinePlayerIndexField) { playerIndex = parsePlayerIndexField(fieldValue); } else if (fieldName.Trim() == gameLineSurvivor1ResultField) { surv1Result = parsePlayerResultField(fieldValue); } else if (fieldName.Trim() == gameLineSurvivor2ResultField) { surv2Result = parsePlayerResultField(fieldValue); } else if (fieldName.Trim() == gameLineSurvivor3ResultField) { surv3Result = parsePlayerResultField(fieldValue); } else if (fieldName.Trim() == gameLineSurvivor4ResultField) { surv4Result = parsePlayerResultField(fieldValue); } else if (fieldName.Trim() == gameLineDate) { gameDate = Utils.parseDateFromDdMmYyyyString(fieldValue); } // Bloodpoints else if (fieldName.Trim() == gameLineSurvivor1BP) { rememberBP(PlayerIndex.Survivor1, fieldValue); } else if (fieldName.Trim() == gameLineSurvivor2BP) { rememberBP(PlayerIndex.Survivor2, fieldValue); } else if (fieldName.Trim() == gameLineSurvivor3BP) { rememberBP(PlayerIndex.Survivor3, fieldValue); } else if (fieldName.Trim() == gameLineSurvivor4BP) { rememberBP(PlayerIndex.Survivor4, fieldValue); } else if (fieldName.Trim() == gameLineKillerBP) { rememberBP(PlayerIndex.Killer, fieldValue); } else if (fieldName.ToLower().Trim() == gameLineGameType.ToLower()) { gameType = Stats.getGameTypeEnumFromString(fieldValue); Dbg.assert(gameType != GameType.Error, "Loaded wrong game type"); } } // Create game object game = new GameResult(playerIndex, surv1Result, surv2Result, surv3Result, surv4Result, gameType); // Set date if (gameDate != DateTime.MinValue) { game.setDate(gameDate); } // Set BP for (int player = (int)PlayerIndex.Survivor1; player <= (int)PlayerIndex.Killer; player++) { game.setBpAmount(( PlayerIndex )player, bloodpoints[player]); } void rememberBP(PlayerIndex player, string fieldValue) { bloodpoints[( int )player] = EndscoreBpDigitGfx.INVALID_BP_AMOUNT; fieldValue = fieldValue.Trim(); if (fieldValue != "") { bloodpoints[(int)player] = int.Parse(fieldValue); } } return(game); }