mirror of
https://github.com/uberhalit/SekiroFpsUnlockAndMore.git
synced 2026-06-13 09:57:55 +00:00
Added an option to output player death counter and kill counter to files. Useful for display on twitch stream.
This commit is contained in:
parent
f0ad1e49fa
commit
8ffe1615e4
1 changed files with 98 additions and 13 deletions
|
|
@ -11,7 +11,9 @@ using System.Windows.Threading;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Timers;
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
namespace SekiroFpsUnlockAndMore
|
namespace SekiroFpsUnlockAndMore
|
||||||
{
|
{
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
|
|
@ -26,18 +28,27 @@ namespace SekiroFpsUnlockAndMore
|
||||||
internal long _offset_resolution_default = 0x0;
|
internal long _offset_resolution_default = 0x0;
|
||||||
internal long _offset_resolution_scaling_fix = 0x0;
|
internal long _offset_resolution_scaling_fix = 0x0;
|
||||||
internal long _offset_fovsetting = 0x0;
|
internal long _offset_fovsetting = 0x0;
|
||||||
|
//game stat offsets
|
||||||
|
internal long _offset_player_deaths = 0x0;
|
||||||
|
internal long _pointer_player_deaths = 0x0;
|
||||||
internal long _offset_timescale = 0x0;
|
internal long _offset_timescale = 0x0;
|
||||||
internal long _offset_timescale_player = 0x0;
|
internal long _offset_timescale_player = 0x0;
|
||||||
internal bool _use_resolution_720 = false;
|
internal bool _use_resolution_720 = false;
|
||||||
|
internal long _offset_total_kills = 0x0;
|
||||||
|
internal long _pointer_total_kills = 0x0;
|
||||||
|
|
||||||
|
internal const string deathCounterFilename = "DeathCouner.txt";
|
||||||
internal SettingsService _settingsService;
|
internal SettingsService _settingsService;
|
||||||
internal readonly DispatcherTimer _dispatcherTimerCheck = new DispatcherTimer();
|
internal const string totalKillsFilename = "TotalKillsCounter.txt";
|
||||||
|
|
||||||
|
internal readonly Timer _statRecordTimer = new Timer();
|
||||||
|
internal readonly DispatcherTimer _dispatcherTimerCheck = new DispatcherTimer();
|
||||||
internal bool _running = false;
|
internal bool _running = false;
|
||||||
internal string _logPath;
|
internal string _logPath;
|
||||||
internal bool _retryAccess = true;
|
internal bool _retryAccess = true;
|
||||||
internal RECT _windowRect;
|
internal RECT _windowRect;
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +86,10 @@ namespace SekiroFpsUnlockAndMore
|
||||||
});
|
});
|
||||||
_dispatcherTimerCheck.Interval = new TimeSpan(0, 0, 0, 2);
|
_dispatcherTimerCheck.Interval = new TimeSpan(0, 0, 0, 2);
|
||||||
_dispatcherTimerCheck.Start();
|
_dispatcherTimerCheck.Start();
|
||||||
}
|
|
||||||
|
_statRecordTimer.Elapsed += new ElapsedEventHandler(StatReadTimer);
|
||||||
|
_statRecordTimer.Interval = 1500;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// On window closing.
|
/// On window closing.
|
||||||
|
|
@ -88,7 +102,9 @@ namespace SekiroFpsUnlockAndMore
|
||||||
UnregisterHotKey(hWnd, 9009);
|
UnregisterHotKey(hWnd, 9009);
|
||||||
if (_gameAccessHwnd != IntPtr.Zero)
|
if (_gameAccessHwnd != IntPtr.Zero)
|
||||||
CloseHandle(_gameAccessHwnd);
|
CloseHandle(_gameAccessHwnd);
|
||||||
}
|
|
||||||
|
_statRecordTimer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Windows Message queue (Wndproc) to catch HotKeyPressed
|
/// Windows Message queue (Wndproc) to catch HotKeyPressed
|
||||||
|
|
@ -288,6 +304,29 @@ namespace SekiroFpsUnlockAndMore
|
||||||
this.cbFov.IsEnabled = false;
|
this.cbFov.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Game stats
|
||||||
|
_offset_player_deaths = patternScan.FindPatternInternal(_gameAccessHwndStatic, procList[gameIndex].MainModule, GameData.PATTERN_PLAYER_DEATHS, GameData.PATTERN_PLAYER_DEATHS_MASK, ' ');
|
||||||
|
Debug.WriteLine("Player Deaths found at: 0x" + _offset_player_deaths.ToString("X"));
|
||||||
|
if (!IsValidAddress(_offset_player_deaths))
|
||||||
|
{
|
||||||
|
LogToFile("Player death counter not found...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pointer_player_deaths = Read<Int64>(_gameAccessHwndStatic, DereferenceStaticX64Pointer(_gameAccessHwndStatic, _offset_player_deaths, 0)) + 0x90;
|
||||||
|
}
|
||||||
|
|
||||||
|
_offset_total_kills = patternScan.FindPatternInternal(_gameProc, procList[gameIndex].MainModule, GameData.PATTERN_TOTAL_KILLS, GameData.PATTERN_TOTAL_KILLS_MASK, ' ') + GameData.PATTERN_TOTAL_KILLS_OFFSET;
|
||||||
|
Debug.WriteLine("Total kills found at: 0x" + _offset_total_kills.ToString("X"));
|
||||||
|
if (!IsValidAddress(_offset_total_kills))
|
||||||
|
{
|
||||||
|
LogToFile("Total kills counter not found...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_pointer_total_kills = DereferenceStaticX64Pointer(_gameAccessHwndStatic, _offset_total_kills, 0);
|
||||||
|
}
|
||||||
|
|
||||||
this.cbBorderless.IsEnabled = true;
|
this.cbBorderless.IsEnabled = true;
|
||||||
|
|
||||||
long offset_pTimeRelated = patternScan.FindPatternInternal(GameData.PATTERN_TIMESCALE, GameData.PATTERN_TIMESCALE_MASK, ' ');
|
long offset_pTimeRelated = patternScan.FindPatternInternal(GameData.PATTERN_TIMESCALE, GameData.PATTERN_TIMESCALE_MASK, ' ');
|
||||||
|
|
@ -353,7 +392,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
|
|
||||||
this.bPatch.IsEnabled = true;
|
this.bPatch.IsEnabled = true;
|
||||||
|
|
||||||
_running = true;
|
_running = true;
|
||||||
_dispatcherTimerCheck.Stop();
|
_dispatcherTimerCheck.Stop();
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
@ -655,11 +694,32 @@ namespace SekiroFpsUnlockAndMore
|
||||||
UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the hexadecimal representation of an IEEE-754 floating point number
|
/// Reads some hidden stats and outputs them to text files. Use to display counters on Twitch stream or just look at them and get disspointed
|
||||||
/// </summary>
|
/// </summary
|
||||||
/// <param name="input">The floating point number.</param>
|
private void StatReadTimer(object sender, EventArgs e)
|
||||||
/// <returns>The hexadecimal representation of the input.</returns>
|
{
|
||||||
|
if (IsValidAddress(_pointer_player_deaths))
|
||||||
|
{
|
||||||
|
int playerDeaths = Read<Int32>(_gameAccessHwndStatic, _pointer_player_deaths);
|
||||||
|
//Debug.WriteLine("[STAT]Player deaths: " + playerDeaths);
|
||||||
|
LogStatFile(deathCounterFilename, playerDeaths.ToString());
|
||||||
|
|
||||||
|
if (IsValidAddress(_pointer_total_kills))
|
||||||
|
{
|
||||||
|
int totalKills = Read<Int32>(_gameAccessHwndStatic, _pointer_total_kills);
|
||||||
|
totalKills -= playerDeaths; //Since this value seems to track every death, including the player
|
||||||
|
//Debug.WriteLine("[STAT]Enemies killed: " + totalKills);
|
||||||
|
LogStatFile(totalKillsFilename, totalKills.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the hexadecimal representation of an IEEE-754 floating point number
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">The floating point number.</param>
|
||||||
|
/// <returns>The hexadecimal representation of the input.</returns>
|
||||||
private static string GetHexRepresentationFromFloat(float input)
|
private static string GetHexRepresentationFromFloat(float input)
|
||||||
{
|
{
|
||||||
uint f = BitConverter.ToUInt32(BitConverter.GetBytes(input), 0);
|
uint f = BitConverter.ToUInt32(BitConverter.GetBytes(input), 0);
|
||||||
|
|
@ -848,7 +908,27 @@ namespace SekiroFpsUnlockAndMore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateStatus(string text, Brush color)
|
/// <summary>
|
||||||
|
/// Logs stat values to separate files for the use in OBS
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename">File name</param>
|
||||||
|
/// <param name="msg">Just a single stat value</param>
|
||||||
|
private void LogStatFile(string filename, string value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (StreamWriter writer = new StreamWriter(filename, false))
|
||||||
|
{
|
||||||
|
writer.Write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Failed writing stat file: " + ex.Message, "Sekiro Fps Unlock And More");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStatus(string text, Brush color)
|
||||||
{
|
{
|
||||||
this.tbStatus.Background = color;
|
this.tbStatus.Background = color;
|
||||||
this.tbStatus.Text = text;
|
this.tbStatus.Text = text;
|
||||||
|
|
@ -985,7 +1065,12 @@ namespace SekiroFpsUnlockAndMore
|
||||||
if (this.cbPlayerSpeed.IsChecked == true) PatchPlayerSpeed();
|
if (this.cbPlayerSpeed.IsChecked == true) PatchPlayerSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BPatch_Click(object sender, RoutedEventArgs e)
|
private void CbStatChanged(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_statRecordTimer.Enabled = (bool)cbLogStats.IsChecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BPatch_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
PatchGame();
|
PatchGame();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue