private void onStart(object sender, EventArgs e) { if (VerifyProcessRunning()) { activeSlot = saveSlotPointer.Deref <double>(gameProc); } completedAchievements.Clear(); }
private dynamic GetValue(Process p, String type, DeepPointer pointer) { if (type == "int") { int x; pointer.Deref <int>(p, out x); return(x); } else if (type == "uint") { uint x; pointer.Deref <uint>(p, out x); return(x); } else if (type == "float") { float x; pointer.Deref <float>(p, out x); return(x); } else if (type == "byte") { byte x; pointer.Deref <byte>(p, out x); return(x); } else if (type == "bool") { bool x; pointer.Deref <bool>(p, out x); return(x); } else if (type == "short") { short x; pointer.Deref <short>(p, out x); return(x); } else if (type == "sbyte") { sbyte x; pointer.Deref <sbyte>(p, out x); return(x); } else if (type.StartsWith("string")) { String x; var length = Int32.Parse(type.Substring("string".Length)); pointer.Deref(p, out x, length); return(x); } else if (type.StartsWith("byte")) { byte[] x; var length = Int32.Parse(type.Substring("byte".Length)); pointer.Deref(p, out x, length); return(x); } throw new ArgumentException("The provided type is not supported"); }
private dynamic GetValue(Process p, String type, DeepPointer pointer) { if (type == "int") return pointer.Deref<int>(p); else if (type == "uint") return pointer.Deref<uint>(p); else if (type == "float") return pointer.Deref<float>(p); else if (type == "double") return pointer.Deref<double>(p); else if (type == "byte") return pointer.Deref<byte>(p); else if (type == "sbyte") return pointer.Deref<sbyte>(p); else if (type == "short") return pointer.Deref<short>(p); else if (type == "ushort") return pointer.Deref<ushort>(p); else if (type == "bool") return pointer.Deref<bool>(p); else if (type.StartsWith("string")) { var length = Int32.Parse(type.Substring("string".Length)); return pointer.DerefString(p, length); } else if (type.StartsWith("byte")) { var length = Int32.Parse(type.Substring("byte".Length)); return pointer.DerefBytes(p, length); } throw new ArgumentException(string.Format("The provided type, '{0}', is not supported", type)); }
public bool ReadMusicCoroutineInProgress(out long musicCoroutine) { if (!DPMainManagerMusicCoroutine.Deref <long>(BfGameProcess, out musicCoroutine)) { musicCoroutine = -1; return(false); } return(true); }
public bool ReadFirstMusicId(out int songId) { if (!DPMainManagerFirstMusicId.Deref <int>(BfGameProcess, out songId)) { songId = -1; return(false); } return(true); }
public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { if (Game == null) { isHooked = false; } else if (Game.HasExited) { Game = null; isHooked = false; } else { isHooked = xVelocityDP.Deref <float>(Game, out var ignore); } if (!isHooked) { List <Process> GameProcesses = Process.GetProcesses().ToList().FindAll(x => x.ProcessName.StartsWith("bms")); if (GameProcesses.Count > 0) { Game = GameProcesses.First(); velocityTextDP.DerefOffsets(Game, out velocityTextPTR); Game.VirtualProtect(velocityTextPTR, 32, MemPageProtect.PAGE_EXECUTE_READWRITE); isHooked = xVelocityDP.Deref <float>(Game, out var ignore); } } else { float xVel = xVelocityDP.Deref <float>(Game); float yVel = yVelocityDP.Deref <float>(Game); float zVel = zVelocityDP.Deref <float>(Game); double horizontalVelocity = Math.Sqrt(Math.Pow(xVel, 2) + Math.Pow(yVel, 2)); byte[] velocityArray = Encoding.ASCII.GetBytes("hvel: " + horizontalVelocity.ToString("0.00") + " zvel: " + zVel.ToString("0.00")); byte[] outputArray = new byte[32]; for (int i = 0; i < velocityArray.Length; i++) { outputArray[i] = velocityArray[i]; } Game.WriteBytes(velocityTextPTR, outputArray); } }
private void button1_Click(object sender, EventArgs e) //Generate { if (process == null || process.HasExited) { MessageBox.Show("Project64 is not available. Try Connnecting again!", "Process Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); genButton.Enabled = false; } else { byte currentLevel = levelPointer.Deref <byte>(process); genName.Text = segName.Text + " [" + currentLevel.ToString() + "]"; } }
public bool ReadBattlePtr(out long battlePtr) { if (!DPMainManagerBattlePtr.Deref <long>(BfGameProcess, out battlePtr)) { if (!DPMainManagerBattle.Deref <long>(BfGameProcess, out battlePtr)) { battlePtr = -1; return(false); } battlePtr = 0; return(true); } return(true); }
private static dynamic GetValue(Process p, string type, DeepPointer pointer) { switch (type) { case "int": return pointer.Deref<int>(p); case "uint": return pointer.Deref<uint>(p); case "float": return pointer.Deref<float>(p); case "double": return pointer.Deref<double>(p); case "byte": return pointer.Deref<byte>(p); case "sbyte": return pointer.Deref<sbyte>(p); case "short": return pointer.Deref<short>(p); case "ushort": return pointer.Deref<ushort>(p); case "bool": return pointer.Deref<bool>(p); default: if (type.StartsWith("string")) { var length = int.Parse(type.Substring("string".Length)); return pointer.DerefString(p, length); } else if (type.StartsWith("byte")) { var length = int.Parse(type.Substring("byte".Length)); return pointer.DerefBytes(p, length); } break; } throw new ArgumentException($"The provided type, '{type}', is not supported"); }
//Read values regarding achievements from memory and update the display public void UpdateTrackers() { //Add a check for in game if (VerifyProcessRunning() && (activeSlot == 10 || activeSlot == saveSlotPointer.Deref <double>(gameProc))) // && levelId thingy need to get pointer and compare to main menu { //0 good, 1+ bad if (deathsPointer.Deref <double>(gameProc) == 0) { AchievementLabelList[0].Text = "Deathless"; SetTextColor(0, settingsControl.completedColor); } else { AchievementLabelList[0].Text = "Not Deathless"; SetTextColor(0, settingsControl.failedColor); //AchievementLabelList[0].ForeColor = <SETTING_FAILED_COLOUR> } //0 good, 1+ bad if (commonEnemiesKilledPointer.Deref <double>(gameProc) == 0) { AchievementLabelList[2].Text = "Pacifist"; SetTextColor(2, settingsControl.completedColor); } else { AchievementLabelList[2].Text = "Murderer"; SetTextColor(2, settingsControl.failedColor); } if (!completedAchievements.Contains(AchievementLabelList[5].Text)) { double roomsVisited = roomsVisitedPointer.Deref <double>(gameProc); //454 Done AchievementLabelList[4].Text = (roomsVisited == 454) ? "Explored" : String.Format("{0}/454", roomsVisited); if (roomsVisited == 454) { completedAchievements.Add(AchievementLabelList[5].Text); AchievementLabelList[4].Text = "Explored"; SetTextColor(4, settingsControl.completedColor); } else { AchievementLabelList[4].Text = String.Format("{0}/454", roomsVisited); SetTextColor(4, settingsControl.inProgressColor); } } //1 done if (!completedAchievements.Contains(AchievementLabelList[7].Text)) { double shroomDelivered = shroomDeliveredPointer.Deref <double>(gameProc); if (shroomDelivered == 1) { completedAchievements.Add(AchievementLabelList[7].Text); AchievementLabelList[6].Text = "Delivered"; SetTextColor(6, settingsControl.completedColor); } else { AchievementLabelList[6].Text = (shroomFoundPointer.Deref <double>(gameProc) == 1) ? "Not Delivered" : "Not Found"; SetTextColor(6, settingsControl.inProgressColor); } } if (!completedAchievements.Contains(AchievementLabelList[9].Text)) { //1 done in BugsDelivered, BugCount is how many are collected double bugsDelivered = bugsDeliveredPointer.Deref <double>(gameProc); if (bugsDelivered == 1) { completedAchievements.Add(AchievementLabelList[9].Text); AchievementLabelList[8].Text = "Delivered"; SetTextColor(8, settingsControl.completedColor); } else { AchievementLabelList[8].Text = String.Format("{0}/20", bugCountPointer.Deref <double>(gameProc)); SetTextColor(8, settingsControl.inProgressColor); } } if (!completedAchievements.Contains(AchievementLabelList[11].Text)) { //1 done double choir = choirPointer.Deref <double>(gameProc); if (choir == 1) { completedAchievements.Add(AchievementLabelList[11].Text); AchievementLabelList[10].Text = "Killed"; SetTextColor(10, settingsControl.completedColor); } else { AchievementLabelList[10].Text = "Alive"; SetTextColor(10, settingsControl.inProgressColor); } } if (!completedAchievements.Contains(AchievementLabelList[13].Text)) { //17 is done, tracks maxhealth and insane starts with 1 so max health is 18, -1 means 17 fragments double maxHealth = maxHealthPointer.Deref <double>(gameProc); if (maxHealth == 18) { completedAchievements.Add(AchievementLabelList[13].Text); SetTextColor(12, settingsControl.completedColor); } else { SetTextColor(12, settingsControl.inProgressColor); } AchievementLabelList[12].Text = String.Format("{0}/17", maxHealth - 1); } if (diccifultyPointer.Deref <double>(gameProc) == 4) { AchievementLabelList[14].Text = "Insane"; SetTextColor(14, settingsControl.completedColor); } else { AchievementLabelList[14].Text = "Not insane"; SetTextColor(14, settingsControl.failedColor); } if (greenLeafPointer.Deref <double>(gameProc) == 1) { AchievementLabelList[16].Text = "True End"; SetTextColor(16, settingsControl.completedColor); } else { AchievementLabelList[16].Text = "Normal End"; SetTextColor(16, settingsControl.inProgressColor); } } }
public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { if (Game == null || Game.HasExited) { Game = null; var process = Process.GetProcessesByName("SuperMeatBoy").FirstOrDefault(); if (process != null) { Game = process; } OldTitleScreenShowing = false; } if (Model == null) { Model = new TimerModel() { CurrentState = state }; state.OnStart += state_OnStart; } if (Game != null) { float time; TimeSpan levelTime = OldLevelTime ?? TimeSpan.Zero; bool isInALevel; IsInALevel.Deref <bool>(Game, out isInALevel); if (isInALevel) { try { LevelTimer.Deref <float>(Game, out time); levelTime = TimeSpan.FromSeconds(time); } catch { } } //AliveTimer.Deref<float>(Game, out time); //var aliveTime = TimeSpan.FromSeconds(time); //int deathCounter; //DeathCounter.Deref<int>(Game, out deathCounter); int levelID; LevelID.Deref <int>(Game, out levelID); int chapterID; ChapterID.Deref <int>(Game, out chapterID); int levelType; LevelType.Deref <int>(Game, out levelType); int chapterSelectID; ChapterSelectID.Deref <int>(Game, out chapterSelectID); bool creditsPlaying; CreditsPlaying.Deref <bool>(Game, out creditsPlaying); bool isAtLevelSelect; IsAtLevelSelect.Deref <bool>(Game, out isAtLevelSelect); bool isNotAtLevelEnd; IsNotAtLevelEnd.Deref <bool>(Game, out isNotAtLevelEnd); if (!WasAtLevelEnd && !isNotAtLevelEnd) { WasAtLevelEnd = true; FinishedLevelTime = levelTime; } bool titleScreenShowing; bool couldFetch = TitleScreenShowing.Deref <bool>(Game, out titleScreenShowing); if (!couldFetch) { titleScreenShowing = true; } //bool isTimeRunning = OldLevelTime != levelTime; if (OldLevelTime != null)// && OldLevelTime != null) { if (state.CurrentPhase == TimerPhase.NotRunning && !titleScreenShowing && OldTitleScreenShowing) { Model.Start(); } else if (state.CurrentPhase == TimerPhase.Running) { if (chapterID == 6 && levelID == 99) { if (creditsPlaying && !OldCreditsPlaying) { Model.Split(); //The End } } else { if ((levelType != 0 && levelType != 10) || chapterID == 7) { if (((levelType <= 1) ? (levelID == 20) : true) && !isInALevel && (levelID == 20 && state.CurrentSplitIndex == state.Run.Count - 1 ? WasInALevel //Split earlier for Cotton Alley if it's the last split : (!isAtLevelSelect && WasAtLevelSelect))) { Model.Split(); //Dark World or Cotton Alley } } else if (!creditsPlaying && OldCreditsPlaying) { Model.Split(); //Chapter Splits } } if (titleScreenShowing && !creditsPlaying) { Model.Reset(); } } if (OldLevelTime > levelTime) { //OldDeathCounter = deathCounter; GameTime += (WasAtLevelEnd ? FinishedLevelTime : OldLevelTime ?? TimeSpan.Zero); WasAtLevelEnd = false; } } #if GAME_TIME state.IsLoading = true; var currentGameTime = GameTime + (WasAtLevelEnd ? FinishedLevelTime : levelTime); state.SetGameTime(currentGameTime < TimeSpan.Zero ? TimeSpan.Zero : currentGameTime); #endif //WasTimeRunning = isTimeRunning; //OldLevelTime = levelTime; OldLevelTime = levelTime; OldLevelID = levelID; OldChapterSelectID = chapterSelectID; OldCreditsPlaying = creditsPlaying; WasAtLevelSelect = isAtLevelSelect; WasInALevel = isInALevel; OldTitleScreenShowing = titleScreenShowing; } }
private static dynamic GetValue(Process p, string type, DeepPointer pointer) { switch (type) { case "int": return(pointer.Deref <int>(p)); case "uint": return(pointer.Deref <uint>(p)); case "long": return(pointer.Deref <long>(p)); case "ulong": return(pointer.Deref <ulong>(p)); case "float": return(pointer.Deref <float>(p)); case "double": return(pointer.Deref <double>(p)); case "byte": return(pointer.Deref <byte>(p)); case "sbyte": return(pointer.Deref <sbyte>(p)); case "short": return(pointer.Deref <short>(p)); case "ushort": return(pointer.Deref <ushort>(p)); case "bool": return(pointer.Deref <bool>(p)); default: if (type.StartsWith("string")) { var length = int.Parse(type.Substring("string".Length)); return(pointer.DerefString(p, length)); } else if (type.StartsWith("byte")) { var length = int.Parse(type.Substring("byte".Length)); return(pointer.DerefBytes(p, length)); } break; } throw new ArgumentException($"The provided type, '{type}', is not supported"); }
void MemoryReadThread() { Debug.WriteLine("[NoLoads] MemoryReadThread"); while (!_cancelSource.IsCancellationRequested) { try { Debug.WriteLine("[NoLoads] Waiting for quake4.exe..."); Process game; while ((game = GetGameProcess()) == null) { Thread.Sleep(250); if (_cancelSource.IsCancellationRequested) { return; } } Debug.WriteLine("[NoLoads] Got games process!"); uint frameCounter = 0; bool prevIsLoading = false; bool prevIsCutscene = false; string prevStreamGroupId = String.Empty; bool loadingStarted = false; while (!game.HasExited) { bool isLoading; bool isCutscene; string streamGroupId = String.Empty; _levelNamePtr.DerefString(game, 30, out streamGroupId); streamGroupId = streamGroupId.ToLower(); _isLoadingPtr.Deref(game, out isLoading); _isCutscenePtr.Deref(game, out isCutscene); if (streamGroupId != prevStreamGroupId && streamGroupId != null || prevIsCutscene != isCutscene) { if (prevStreamGroupId == LevelName.l01_airDefence1 && streamGroupId == LevelName.l02_airDefence2) { Split(SplitArea.l01, frameCounter); } else if (prevStreamGroupId == LevelName.l02_airDefence2 && streamGroupId == LevelName.l03_hangar1) { Split(SplitArea.l02, frameCounter); } else if (prevStreamGroupId == LevelName.l03_hangar1 && streamGroupId == LevelName.l04_hangar2) { Split(SplitArea.l03, frameCounter); } else if (prevStreamGroupId == LevelName.l04_hangar2 && streamGroupId == LevelName.l05_mcclanding) { Split(SplitArea.l04, frameCounter); } else if (prevStreamGroupId == LevelName.l05_mcclanding && streamGroupId == LevelName.l06_mcc1) { Split(SplitArea.l05, frameCounter); } else if (prevStreamGroupId == LevelName.l06_mcc1 && streamGroupId == LevelName.l07_convoy1) { Split(SplitArea.l06, frameCounter); } else if (prevStreamGroupId == LevelName.l07_convoy1 && streamGroupId == LevelName.l08_buildingb) { Split(SplitArea.l07, frameCounter); } else if (prevStreamGroupId == LevelName.l08_buildingb && streamGroupId == LevelName.l09_convoy2) { Split(SplitArea.l08, frameCounter); } else if (prevStreamGroupId == LevelName.l09_convoy2 && streamGroupId == LevelName.l10_convoy2b) { Split(SplitArea.l09, frameCounter); } else if (prevStreamGroupId == LevelName.l10_convoy2b && streamGroupId == LevelName.l11_hub1) { Split(SplitArea.l10, frameCounter); } else if (prevStreamGroupId == LevelName.l11_hub1 && streamGroupId == LevelName.l12_hub2) { Split(SplitArea.l11, frameCounter); } else if (prevStreamGroupId == LevelName.l12_hub2 && streamGroupId == LevelName.l13_medlabs) { Split(SplitArea.l12, frameCounter); } else if (prevStreamGroupId == LevelName.l13_medlabs && streamGroupId == LevelName.l14_walker) { Split(SplitArea.l13, frameCounter); } else if (prevStreamGroupId == LevelName.l14_walker && streamGroupId == LevelName.l15_dispersal) { Split(SplitArea.l14, frameCounter); } else if (prevStreamGroupId == LevelName.l15_dispersal && streamGroupId == LevelName.l16_recomp) { Split(SplitArea.l15, frameCounter); } else if (prevStreamGroupId == LevelName.l16_recomp && streamGroupId == LevelName.l17_purification) { Split(SplitArea.l16, frameCounter); } else if (prevStreamGroupId == LevelName.l17_purification && streamGroupId == LevelName.l18_wasteDisposal) { Split(SplitArea.l17, frameCounter); } else if (prevStreamGroupId == LevelName.l18_wasteDisposal && streamGroupId == LevelName.l19_mcc2) { Split(SplitArea.l18, frameCounter); } else if (prevStreamGroupId == LevelName.l19_mcc2 && streamGroupId == LevelName.l20_storage1) { Split(SplitArea.l19, frameCounter); } else if (prevStreamGroupId == LevelName.l20_storage1 && streamGroupId == LevelName.l21_storage2) { Split(SplitArea.l20, frameCounter); } else if (prevStreamGroupId == LevelName.l21_storage2 && streamGroupId == LevelName.l22_storage1) { Split(SplitArea.l21, frameCounter); } else if (prevStreamGroupId == LevelName.l22_storage1 && streamGroupId == LevelName.l23_tram1) { Split(SplitArea.l22, frameCounter); } else if (prevStreamGroupId == LevelName.l23_tram1 && streamGroupId == LevelName.l24_tram1b) { Split(SplitArea.l23, frameCounter); } else if (prevStreamGroupId == LevelName.l24_tram1b && streamGroupId == LevelName.l25_process1) { Split(SplitArea.l24, frameCounter); } else if (prevStreamGroupId == LevelName.l25_process1 && streamGroupId == LevelName.l26_process2) { Split(SplitArea.l25, frameCounter); } else if (prevStreamGroupId == LevelName.l26_process2 && streamGroupId == LevelName.l27_process1) { Split(SplitArea.l26, frameCounter); } else if (prevStreamGroupId == LevelName.l27_process1 && streamGroupId == LevelName.l28_network1) { Split(SplitArea.l27, frameCounter); } else if (prevStreamGroupId == LevelName.l28_network1 && streamGroupId == LevelName.l29_network2) { Split(SplitArea.l28, frameCounter); } else if (prevStreamGroupId == LevelName.l29_network2 && streamGroupId == LevelName.l30_core1) { Split(SplitArea.l29, frameCounter); } else if (prevStreamGroupId == LevelName.l30_core1 && streamGroupId == LevelName.l31_core2) { Split(SplitArea.l30, frameCounter); } else if (streamGroupId == LevelName.l31_core2 && isCutscene) { Split(SplitArea.l31, frameCounter); } else if (streamGroupId == LevelName.l01_airDefence1 && isCutscene == true && prevIsCutscene == false) { //Reset in game timer _uiThread.Post(d => { if (this.OnFirstLevelLoading != null) { this.OnFirstLevelLoading(this, EventArgs.Empty); } }, null); // And instantly start it _uiThread.Post(d => { if (this.OnPlayerGainedControl != null) { this.OnPlayerGainedControl(this, EventArgs.Empty); } }, null); } } _isLoadingPtr.Deref(game, out isLoading); if (isLoading != prevIsLoading) { if (isLoading) { Debug.WriteLine(String.Format("[NoLoads] Load Start - {0}", frameCounter)); loadingStarted = true; // pause game timer _uiThread.Post(d => { if (this.OnLoadStarted != null) { this.OnLoadStarted(this, EventArgs.Empty); } }, null); } else { Debug.WriteLine(String.Format("[NoLoads] Load End - {0}", frameCounter)); if (loadingStarted) { loadingStarted = false; // unpause game timer _uiThread.Post(d => { if (this.OnLoadFinished != null) { this.OnLoadFinished(this, EventArgs.Empty); } }, null); } } } Debug.WriteLineIf(streamGroupId != prevStreamGroupId, String.Format("[NoLoads] streamGroupId changed from {0} to {1} - {2}", prevStreamGroupId, streamGroupId, frameCounter)); prevStreamGroupId = streamGroupId; prevIsLoading = isLoading; prevIsCutscene = isCutscene; frameCounter++; Thread.Sleep(15); if (_cancelSource.IsCancellationRequested) { return; } } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Thread.Sleep(1000); } } }
void MemoryReadThread() { Debug.WriteLine("[NoLoads] MemoryReadThread"); while (!_cancelSource.IsCancellationRequested) { try { Debug.WriteLine("[NoLoads] Waiting for pc_matador.exe..."); Process game; while ((game = GetGameProcess()) == null) { Thread.Sleep(250); if (_cancelSource.IsCancellationRequested) { return; } } Debug.WriteLine("[NoLoads] Got games process!"); uint frameCounter = 0; while (!game.HasExited && hasDLLInjected) { _isLoadingPtr.Deref(game, out isLoading); if (isLoading != prevIsLoading) { if (isLoading) { Debug.WriteLine(String.Format("[NoLoads] Load Start - {0}", frameCounter)); loadingStarted = true; // pause game timer _uiThread.Post(d => { if (this.OnLoadStarted != null) { this.OnLoadStarted(this, EventArgs.Empty); } }, null); } else { Debug.WriteLine(String.Format("[NoLoads] Load End - {0}", frameCounter)); if (loadingStarted) { loadingStarted = false; // unpause game timer _uiThread.Post(d => { if (this.OnLoadFinished != null) { this.OnLoadFinished(this, EventArgs.Empty); } }, null); } } } prevIsLoading = isLoading; frameCounter++; Thread.Sleep(15); if (_cancelSource.IsCancellationRequested) { return; } } // pause game timer on exit or crash _uiThread.Post(d => { if (this.OnLoadStarted != null) { this.OnLoadStarted(this, EventArgs.Empty); } }, null); isLoading = true; } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Thread.Sleep(1000); } } }
void GameMemoryReadThread() { Trace.WriteLine("[NoLoads] MemoryReadThread"); while (!ListenGameCancelSource.IsCancellationRequested) { try { Trace.WriteLine("[NoLoads] Waiting for game.exe..."); Process game; while ((game = GetGameProcess()) == null) { Thread.Sleep(250); if (ListenGameCancelSource.IsCancellationRequested) { return; } } Trace.WriteLine("[NoLoads] Got game.exe!"); FrameCounter = 0; int prevBufCursor = 0; string prevBuf = String.Empty; string currentMap = String.Empty; string prevCurrentMap = String.Empty; bool prevIsLoading = false; while (!game.HasExited) { LogBufferPtr.DerefString(game, 4096, out string buf); LogBufferCursorPtr.Deref(game, out int bufCursor); IsLoadingPtr.Deref(game, out int ret); IsSavingPtr.Deref(game, out int isSaving); bool isLoading = (ret == 2 || isSaving == 256); string log = String.Empty; if ((!buf.Equals(prevBuf) && !prevBuf.Equals(String.Empty))) { int length = (prevBufCursor > bufCursor) ? 4096 - prevBufCursor : bufCursor - prevBufCursor; log = buf.Substring(prevBufCursor, length); if (prevBufCursor > bufCursor) { log += buf.Substring(0, bufCursor); } string[] logLines = Regex.Split(log, @"(?<=\r\n)"); Debug.WriteLine(String.Format("------bufCursor: {0} prevBufCursor: {1}-------", bufCursor, prevBufCursor)); Debug.WriteLine("--------------------" + FrameCounter + "---------------------"); Debug.Write(log); int cursor = prevBufCursor; uint i = 0; foreach (string line in logLines) { Match validLine = Regex.Match(line, @"^(?:Log:|Init:|ScriptLog:|CutLog:|DevSound:|Localization:|Warning:|ScriptWarning:|Exit:|Uninitialized:).+\r\n"); Match loadMapRegex = Regex.Match(line, @"LoadMap: ([^?]+)\?"); Match splitRegex = Regex.Match(line, @"Bringing Level ([^ ?]+)\.MyLevel up for play"); Match loadTimeRegex = Regex.Match(line, @"Load time (?:.+\\)?([^?]+): (\d+\.\d+) seconds total, (\d+\.\d+) app"); Match saveStartRegex = Regex.Match(line, @"Saving game\.\.\. filename: .+\.usa"); Match saveEndRegex = Regex.Match(line, @"Log: Moving '.+\.tmp' to '.+\.usa'"); if (line.Equals("")) { continue; } // If the line is incorrect, read again from there next frame if (!validLine.Success && i > 0) { Debug.WriteLine("\n[Invalid line] " + line); bufCursor = cursor; if (bufCursor >= 4096) { bufCursor -= 4096; } break; } cursor += line.Length; if (loadMapRegex.Success) { currentMap = loadMapRegex.Groups[1].Value.ToLower(); if (Shrek2Splits.Splits.Any(p => p.Name == currentMap)) { Split(Shrek2Splits.Splits.First(p => p.Name == currentMap).ID, FrameCounter); } } else if (line.Contains(Shrek2Splits.NewGame_MemoryLine)) { ListenGameUIThread.Post(d => { OnNewGame?.Invoke(this, EventArgs.Empty); }, null); } else { if (Shrek2Splits.Splits.Any(p => p.CutSceneTriggers.Any(x => line.Contains(x)))) { var splitValue = Shrek2Splits.Splits.FirstOrDefault(p => p.CutSceneTriggers.Any(x => line.Contains(x))); Split(splitValue.ID, FrameCounter); } } i++; } } if (currentMap != prevCurrentMap) { Debug.WriteLine(String.Format("[NoLoads] Detected map change from \"{0}\" to \"{1}\" - {2}", prevCurrentMap, currentMap, FrameCounter)); if (currentMap == "book_frontend.unr") { ListenGameUIThread.Post(d => { if (this.OnMainMenuLoad != null) { this.OnMainMenuLoad(this, EventArgs.Empty); } }, null); } } if (isLoading != prevIsLoading) { if (isLoading) { Trace.WriteLine("[NoLoads] Loading started - " + FrameCounter); ListenGameUIThread.Post(d => { if (this.OnLoadStart != null) { this.OnLoadStart(this, EventArgs.Empty); } }, null); } else { Trace.WriteLine("[NoLoads] Loading ended - " + FrameCounter); ListenGameUIThread.Post(d => { if (this.OnLoadEnd != null) { this.OnLoadEnd(this, EventArgs.Empty); } }, null); } } FrameCounter++; prevBuf = buf; prevBufCursor = bufCursor; prevCurrentMap = currentMap; prevIsLoading = isLoading; Thread.Sleep(Shrek2Variables.GameLogic_SleepTime); if (ListenGameCancelSource.IsCancellationRequested) { return; } } } catch (Exception ex) { Trace.WriteLine(ex.ToString()); Thread.Sleep(1000); } } }
void MemoryReadThread() { Debug.WriteLine("[NoLoads] MemoryReadThread"); while (!_cancelSource.IsCancellationRequested) { try { Debug.WriteLine("[NoLoads] Waiting for HMA.exe..."); uint frameCounter = 0; Process game; while ((game = GetGameProcess()) == null) { Thread.Sleep(250); if (_cancelSource.IsCancellationRequested) { return; } } Debug.WriteLine("[NoLoads] Got games process!"); float prevMenuLoadingScreenProgress = -1; float prevIsInGameOrMenu = -1; float prevIsNotLoading = -1; float prevIsSavingOrLoading = -1; int prevTimer = -1; string prevCurrentScene = null; float menuLoadingScreenProgress = -1; float isInGameOrMenu = -1; float isNotLoading = -1; float isSavingOrLoading = -1; int timer = -1; string currentScene = ""; bool finalSplitFlag = false; Stats stats; while (!game.HasExited && !_cancelSource.IsCancellationRequested) { currentScene = ""; bool isMenuLoadingScreenProgressValid = _MenuLoadingScreenProgress.Deref(game, out menuLoadingScreenProgress); bool isIsNotLoadingValid = _IsNotLoading.Deref(game, out isNotLoading); bool isIsSavingOrLoadingValid = _IsSavingOrLoading.Deref(game, out isSavingOrLoading); bool isCurrentSceneValid = _CurrentScene.DerefString(game, 50, out currentScene); bool isTimerValid = _Timer.Deref(game, out timer); bool isStatsValid = _Stats.Deref <Stats>(game, out stats); var scene = currentScene?.ToLower(); if (isCurrentSceneValid && currentScene != prevCurrentScene) { Debug.WriteLine($"Scene changed to {currentScene}"); if (scene.Contains("premission") || scene.Contains("intro")) { try { CurrentLevel = (SplitArea)Int32.Parse(Regex.Match(scene, "m(\\d+)\\\\").Groups[1].Value); Debug.WriteLine($"Current level changed to {CurrentLevel}"); if (_settings.FirstLevel.HasValue && CurrentLevel == _settings.FirstLevel) { Debug.WriteLine($"First level loaded"); _uiThread.Post(d => { OnFirstLevelLoaded?.Invoke(this, EventArgs.Empty); }, null); } } catch (Exception ex) { CurrentLevel = null; Debug.WriteLine(ex.ToString()); } } else if (CurrentLevel.HasValue && ((PostMissionSceneNames.ContainsKey(CurrentLevel.Value) && scene.Contains(PostMissionSceneNames[CurrentLevel.Value])) || scene.Contains("postmission"))) { Debug.WriteLine($"Splitting {CurrentLevel.Value}"); Split(CurrentLevel.Value, frameCounter); } finalSplitFlag = false; } if (isStatsValid && CurrentLevel.HasValue && CurrentLevel.Value == SplitArea.Requiem && isCurrentSceneValid && currentScene.ToLower().Contains("main") && !finalSplitFlag && stats.m_TargetsKilled == 13) { finalSplitFlag = true; Split(CurrentLevel.Value, frameCounter); } if ((isIsNotLoadingValid && isNotLoading == 0 && (scene.Contains("main") || scene.Contains("premission"))) || (isIsSavingOrLoadingValid && isSavingOrLoading != 0 && scene.Contains("saveandcontinue")) || (isMenuLoadingScreenProgressValid && menuLoadingScreenProgress != 1) ) { IsLoading = true; } else { IsLoading = false; } prevMenuLoadingScreenProgress = isMenuLoadingScreenProgressValid ? menuLoadingScreenProgress : prevMenuLoadingScreenProgress; prevIsInGameOrMenu = isMenuLoadingScreenProgressValid ? isInGameOrMenu : prevIsInGameOrMenu; prevIsNotLoading = isIsNotLoadingValid ? isNotLoading : prevIsNotLoading; prevIsSavingOrLoading = isIsSavingOrLoadingValid ? isSavingOrLoading : prevIsSavingOrLoading; prevTimer = isTimerValid ? timer : prevTimer; prevCurrentScene = isCurrentSceneValid ? currentScene : prevCurrentScene; frameCounter++; Thread.Sleep(15); } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Thread.Sleep(1000); } } }
public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { if (Game == null || Game.HasExited) { Game = null; var process = Process.GetProcessesByName("GrooveCity").FirstOrDefault(); if (process != null) { Game = process; } } if (!state.Run.CustomComparisons.Contains("Game Time")) { state.Run.CustomComparisons.Add("Game Time"); } if (Model == null) { Model = new TimerModel() { CurrentState = state }; state.OnStart += state_OnStart; } if (Game != null) { float time; //LevelTimer.Deref<float>(Game, out time); //var levelTime = TimeSpan.FromSeconds(time); AliveTimer.Deref <float>(Game, out time); var aliveTime = TimeSpan.FromSeconds(time); //int deathCounter; //DeathCounter.Deref<int>(Game, out deathCounter); int levelID; LevelID.Deref <int>(Game, out levelID); //bool isTimeRunning = OldLevelTime != levelTime; if (OldAliveTime != null)// && OldLevelTime != null) { if (levelID != OldLevelID && levelID >= 6 && levelID <= 22 && levelID != 7 && levelID != 8 && levelID != 18) { if (state.CurrentPhase == TimerPhase.NotRunning && levelID == 6) { Model.Start(); } else if (state.CurrentPhase == TimerPhase.Running) { Model.Split(); } } if (levelID == 4 && state.CurrentPhase == TimerPhase.Running) { Model.Reset(); } if (OldAliveTime > aliveTime) { //OldDeathCounter = deathCounter; GameTime += OldAliveTime ?? TimeSpan.Zero; } } state.IsLoading = true; state.CurrentGameTime = GameTime + aliveTime; //WasTimeRunning = isTimeRunning; //OldLevelTime = levelTime; OldAliveTime = aliveTime; OldLevelID = levelID; } }