Compare commits

..

No commits in common. "master" and "1.2.5.0" have entirely different histories.

5 changed files with 36 additions and 144 deletions

View file

@ -164,7 +164,7 @@ Whenever you upgrade your prosthetic arm the maximum spirit emblem capacity will
Slow down the game to beat a boss like a game journalist or speed it up and become gud. Game speed acts as a global time scale and is used by the game itself to create a dramatic effect in a few cutscenes. All game physics (even opening the menu) will be affected equally: all time-critical windows like dodge and deflect will be proportionally prolonged or shortened while the amount of damage given and taken as well as all other damage physics will be unaltered. A hit from an enemy on 150% game speed will do the exact same damage as on 80%, the deflect window on 50% is exactly twice as long as on 100% and so on. Of course, Sekiro himself will be affected by the speed too so even though a time window might be different now, the speed which you can react on it is different too. Can be toggled by pressing CTRL+M. Be aware that both speed modifications can potentially crash the game in certain cutscenes and NPC interactions so use them with caution. Slow down the game to beat a boss like a game journalist or speed it up and become gud. Game speed acts as a global time scale and is used by the game itself to create a dramatic effect in a few cutscenes. All game physics (even opening the menu) will be affected equally: all time-critical windows like dodge and deflect will be proportionally prolonged or shortened while the amount of damage given and taken as well as all other damage physics will be unaltered. A hit from an enemy on 150% game speed will do the exact same damage as on 80%, the deflect window on 50% is exactly twice as long as on 100% and so on. Of course, Sekiro himself will be affected by the speed too so even though a time window might be different now, the speed which you can react on it is different too. Can be toggled by pressing CTRL+M. Be aware that both speed modifications can potentially crash the game in certain cutscenes and NPC interactions so use them with caution.
### On 'Player speed': ### On 'Player speed':
This modifier enables you to control Sekiro's speed independently from general game speed. Combat physics however are not guaranteed to stay the same on every setting. For example if you increase player speed you will be able to react to an attack faster but your own 'deflect' window is shorter now because you move faster. Use this to explore the world or to keep player speed near normal while altering general game speed. Grappling as well as jumping is handled by game speed while falling damage is calculated based on player speed so take care when grappling to a lower level with a low game speed and high player speed as this could instantly kill you as the game thinks you fell to death. Can be toggled by pressing CTRL+M. This modifier enables you to control Sekiro's speed independently from general game speed. Combat physics however are not guaranteed to stay the same on every setting. For example if you increase player speed you will be able to react to an attack faster but your own 'deflect' window is shorter now because you move faster. Use this to explore the world or to keep player speed near normal while altering general game speed. Grappling as well as jumping is handled by game speed while falling damage is calculated based on player speed so take care when grappling to a lower level with a low game speed and high player speed as this could instantly kill you as the game thinks you fell to death.
Be aware that both speed modifications can potentially crash the game in certain cutscenes and NPC interactions so use them with caution. Be aware that both speed modifications can potentially crash the game in certain cutscenes and NPC interactions so use them with caution.
## Troubleshooting: ## Troubleshooting:
@ -190,7 +190,7 @@ Be aware that both speed modifications can potentially crash the game in certain
## Preview ## Preview
[![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/825b3ef500ce18358566b0ec96a74555eddf2603/68747470733a2f2f692e696d6775722e636f6d2f4868396335634a2e706e67)](#) [![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/998730c9a8d472c8e426f61d0dde589661b4f378/68747470733a2f2f692e696d6775722e636f6d2f466249424271742e706e67)](#)
### Unlocked framerate ### Unlocked framerate
[![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/53f52adb98a5111b31538466f91b58599d56d6d7/68747470733a2f2f692e696d6775722e636f6d2f4c4c524a5a554c2e706e67)](#) [![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/53f52adb98a5111b31538466f91b58599d56d6d7/68747470733a2f2f692e696d6775722e636f6d2f4c4c524a5a554c2e706e67)](#)
@ -240,12 +240,6 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
## Version History ## Version History
* v1.2.5.2 (2020-11-02)
* updated death penalties code to latest version 1.05
* added game version 1.05 (1.5.0.0) to supported versions
* v1.2.5.1 (2020-02-04)
* added support for windows' high contrast mode (thanks to [khvorov45](https://github.com/khvorov45) for pointing it out)
* focus of the game won't be stolen anymore when OBS and the utility try to write/read the stats log files at the same time
* v1.2.5.0 (2019-05-04) * v1.2.5.0 (2019-05-04)
* added feature to automatically loot enemies * added feature to automatically loot enemies
* v1.2.4.0 (2019-05-02) * v1.2.4.0 (2019-05-02)

View file

@ -7,10 +7,9 @@ namespace SekiroFpsUnlockAndMore
internal const string PROCESS_NAME = "sekiro"; internal const string PROCESS_NAME = "sekiro";
internal const string PROCESS_TITLE = "Sekiro"; internal const string PROCESS_TITLE = "Sekiro";
internal const string PROCESS_DESCRIPTION = "Shadows Die Twice"; internal const string PROCESS_DESCRIPTION = "Shadows Die Twice";
internal const string PROCESS_EXE_VERSION = "1.5.0.0"; internal const string PROCESS_EXE_VERSION = "1.4.0.0";
internal static readonly string[] PROCESS_EXE_VERSION_SUPPORTED_LEGACY = new string[3] internal static readonly string[] PROCESS_EXE_VERSION_SUPPORTED = new string[2]
{ {
"1.4.0.0",
"1.3.0.0", "1.3.0.0",
"1.2.0.0" "1.2.0.0"
}; };
@ -194,7 +193,7 @@ namespace SekiroFpsUnlockAndMore
/** /**
Controls camera pitch. xmm4 holds new pitch from a calculation while rsi+170 holds current one from mouse so we overwrite xmm4 with the old pitch value. Controls camera pitch. xmm4 holds new pitch from a calculation while rps+170 holds current one from mouse so we overwrite xmm4 with the old pitch value.
000000014073AF86 | 0F29A5 70080000 | movaps xmmword ptr ss:[rbp+870],xmm4 | code inject overwrite from here 000000014073AF86 | 0F29A5 70080000 | movaps xmmword ptr ss:[rbp+870],xmm4 | code inject overwrite from here
000000014073AF8D | 0F29A5 80080000 | movaps xmmword ptr ss:[rbp+880],xmm4 | jump back here from code inject 000000014073AF8D | 0F29A5 80080000 | movaps xmmword ptr ss:[rbp+880],xmm4 | jump back here from code inject
000000014073AF94 | 0F29A6 70010000 | movaps xmmword ptr ds:[rsi+170],xmm4 | camPitch, newCamPitch 000000014073AF94 | 0F29A6 70010000 | movaps xmmword ptr ds:[rsi+170],xmm4 | camPitch, newCamPitch
@ -231,6 +230,12 @@ namespace SekiroFpsUnlockAndMore
Controls automatic camera pitch adjust on move on XY-axis. Controls automatic camera pitch adjust on move on XY-axis.
Pointer in rax holds new pitch while rsi+170 holds current one prior movement so we overwrite xmm0 with the old pitch value and then overwrite [rax] with xmm0. Pointer in rax holds new pitch while rsi+170 holds current one prior movement so we overwrite xmm0 with the old pitch value and then overwrite [rax] with xmm0.
Breaks Pitch on emulated controllers... Breaks Pitch on emulated controllers...
000000014073B476 | F3:0F1000 | movss xmm0,dword ptr ds:[rax] | newCamPitch | code inject overwrite from here
000000014073B47A | F3:0F1186 70010000 | movss dword ptr ds:[rsi+170],xmm0 | camPitch
000000014073B482 | F3:0F1085 E4120000 | movss xmm0,dword ptr ss:[rbp+12E4] | jump back here from code inject
000000014073B48A | E8 91BDFFFF | call sekiro.140737220 |
000000014073B48F | 0F28D0 | movaps xmm2,xmm0 |
000000014073B4D6 | F3:0F1000 | movss xmm0,dword ptr ds:[rax] | newCamPitch | code inject overwrite from here 000000014073B4D6 | F3:0F1000 | movss xmm0,dword ptr ds:[rax] | newCamPitch | code inject overwrite from here
000000014073B4DA | F3:0F1186 70010000 | movss dword ptr ds:[rsi+170],xmm0 | camePitch 000000014073B4DA | F3:0F1186 70010000 | movss dword ptr ds:[rsi+170],xmm0 | camePitch
000000014073B4E2 | F3:0F1085 E4120000 | movss xmm0,dword ptr ss:[rbp+12E4] | jump back here from code inject 000000014073B4E2 | F3:0F1085 E4120000 | movss xmm0,dword ptr ss:[rbp+12E4] | jump back here from code inject
@ -330,12 +335,12 @@ namespace SekiroFpsUnlockAndMore
/** /**
sekiro.14066DA30 is used to increase and decrease various player values, in this case it's used to decrease Sen so we skip the call. sekiro.14066B520 is used to increase and decrease various player values, in this case it's used to decrease Sen so we skip the call.
00000001411D32F7 | F344:0F2CE9 | cvttss2si r13d,xmm1 | 0000000141189B74 | F344:0F2CE9 | cvttss2si r13d,xmm1 |
00000001411D32FC | 41:8BD5 | mov edx,r13d | 0000000141189B79 | 41:8BD5 | mov edx,r13d |
00000001411D32FF | 48:8BCF | mov rcx,rdi | 0000000141189B7C | 48:8BCB | mov rcx,rbx |
00000001411D3302 | E8 29A749FF | call sekiro.14066DA30 | -> ManipulatePlayerValues() 0000000141189B7F | E8 FC194EFF | call sekiro.14066B580 | -> ManipulatePlayerValues()
00000001411D3307 | 8B87 60010000 | mov eax,dword ptr ds:[rdi+160] | 0000000141189B84 | 8BAB 60010000 | mov ebp,dword ptr ds:[rbx+160] |
000000014118904F (Version 1.2.0.0) 000000014118904F (Version 1.2.0.0)
*/ */
@ -345,20 +350,6 @@ namespace SekiroFpsUnlockAndMore
internal static readonly byte[] PATCH_DEATHPENALTIES1_DISABLE = new byte[5] { 0x90, 0x90, 0x90, 0x90, 0x90 }; // nop internal static readonly byte[] PATCH_DEATHPENALTIES1_DISABLE = new byte[5] { 0x90, 0x90, 0x90, 0x90, 0x90 }; // nop
/** /**
Here ability points (AP) are decreased and virtual Sen & AP decrease is set. The later 2 values will be shown after death as an indicator on how much of each has been lost. Here ability points (AP) are decreased and virtual Sen & AP decrease is set. The later 2 values will be shown after death as an indicator on how much of each has been lost.
To not have the "Unseen Aid" screen shown everytime we overwrite an additional instruction.
00000001411D33BB | E8 E0110000 | call sekiro.1411D45A0 | -> OnDeath() ability points (AP) decrease
00000001411D33C0 | 45:2BE5 | sub r12d,r13d |
00000001411D33C3 | 44:89A424 A0000000 | mov dword ptr ss:[rsp+A0],r12d | virtual Sen decrease - shows how many Sen got lost after death
00000001411D33CB | 8B8424 90000000 | mov eax,dword ptr ss:[rsp+90] | current AP
00000001411D33D2 | 2BC3 | sub eax,ebx |
00000001411D33D4 | 898424 A4000000 | mov dword ptr ss:[rsp+A4],eax | virtual AP decrease - shows how many APs got lost after death
00000001411D33DB | E8 002B6FFF | call sekiro.1408C5EE0 |
00000001411D33E0 | 48:8B8C24 A0000000 | mov rcx,qword ptr ss:[rsp+A0] |
00000001411D33E8 | 48:8908 | mov qword ptr ds:[rax],rcx | checks if we have lost virtual sen and if not shows "Unseen Aid" screen next spawn
00000001411D33EB | 48:8B0D 562BB802 | mov rcx,qword ptr ds:[143D55F48] |
00000001411D33F2 | 48:85C9 | test rcx,rcx |
LEGACY
0000000141189C68 | 8B00 | mov eax,dword ptr ds:[rax] | 0000000141189C68 | 8B00 | mov eax,dword ptr ds:[rax] |
0000000141189C6A | 8983 60010000 | mov dword ptr ds:[rbx+160],eax | OnDeath() ability points (AP) decrease 0000000141189C6A | 8983 60010000 | mov dword ptr ds:[rbx+160],eax | OnDeath() ability points (AP) decrease
0000000141189C70 | 45:2BFD | sub r15d,r13d | 0000000141189C70 | 45:2BFD | sub r15d,r13d |
@ -369,26 +360,10 @@ namespace SekiroFpsUnlockAndMore
000000014118913A (Version 1.2.0.0) 000000014118913A (Version 1.2.0.0)
*/ */
internal const string PATTERN_DEATHPENALTIES2 = "E8 ?? ?? ?? ?? 45 ?? ?? 44 89 ?? 24 ?? ?? 00 00 8B ?? 24 ?? ?? 00 00 2B ?? 89 ?? 24 ?? ?? 00 00 E8 ?? ?? ?? ?? 48 ?? ?? 24 ?? ?? 00 00 48 ?? ?? 48"; internal const string PATTERN_DEATHPENALTIES2 = "8B ?? 89 83 ?? ?? ?? ?? 45 ?? ?? 44 89 ?? 24 ?? ?? 00 00 2B ?? 89 ?? 24 ?? ?? 00 00 E8";
internal const int PATTERN_DEATHPENALTIES2_OFFSET = 0; internal const int PATTERN_DEATHPENALTIES2_OFFSET = 2;
internal const int PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH = 32; internal const int PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH = 26;
internal static readonly byte[] PATCH_DEATHPENALTIES2_DISABLE = new byte[32] // nop internal static readonly byte[] PATCH_DEATHPENALTIES2_DISABLE = new byte[26] // nop
{
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
};
internal const int PATTERN_DEATHPENALTIES3_OFFSET = 45;
internal const int PATCH_DEATHPENALTIES3_INSTRUCTION_LENGTH = 3;
internal static readonly byte[] PATCH_DEATHPENALTIES3_DISABLE = new byte[3] // nop
{
0x90, 0x90, 0x90
};
internal const string PATTERN_DEATHPENALTIES2_LEGACY = "8B ?? 89 83 ?? ?? ?? ?? 45 ?? ?? 44 89 ?? 24 ?? ?? 00 00 2B ?? 89 ?? 24 ?? ?? 00 00 E8";
internal const int PATTERN_DEATHPENALTIES2_OFFSET_LEGACY = 2;
internal const int PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH_LEGACY = 26;
internal static readonly byte[] PATCH_DEATHPENALTIES2_DISABLE_LEGACY = new byte[26] // nop
{ {
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,

View file

@ -7,7 +7,7 @@
mc:Ignorable="d" mc:Ignorable="d"
Title="Sekiro FPS Unlocker and more v1.2.5" Width="Auto" Height="Auto" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing"> Title="Sekiro FPS Unlocker and more v1.2.5" Width="Auto" Height="Auto" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing">
<Grid x:Name="gMainGrid" Background="#FFF9F9F9"> <Grid Background="#FFF9F9F9">
<DockPanel> <DockPanel>
<StackPanel DockPanel.Dock="Top" Margin="10,10,10,0" Width="300" Height="Auto"> <StackPanel DockPanel.Dock="Top" Margin="10,10,10,0" Width="300" Height="Auto">
<DockPanel LastChildFill="False"> <DockPanel LastChildFill="False">
@ -33,7 +33,7 @@
</StackPanel> </StackPanel>
<CheckBox x:Name="cbLogStats" Margin="0,5,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Log stats (Deaths, Kills) to file for OBS" ToolTip="Check the guide on how to display these on stream with OBS" Checked="CbStatChanged" Unchecked="CbStatChanged" TabIndex="10" /> <CheckBox x:Name="cbLogStats" Margin="0,5,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Log stats (Deaths, Kills) to file for OBS" ToolTip="Check the guide on how to display these on stream with OBS" Checked="CbStatChanged" Unchecked="CbStatChanged" TabIndex="10" />
<Expander x:Name="exGameMods" Margin="-3,5,0,0" Height="Auto" FontSize="14 px" Header="Modifications" IsExpanded="True" TabIndex="11"> <Expander x:Name="exGameMods" Margin="-3,5,0,0" Height="Auto" FontSize="14 px" Header="Modifications" IsExpanded="True" TabIndex="11">
<Grid x:Name="gSubGrid1" Margin="3,1,0,0" Background="#FFF9F9F9"> <Grid Margin="3,1,0,0" Background="#FFF9F9F9">
<StackPanel Width="Auto" Height="Auto"> <StackPanel Width="Auto" Height="Auto">
<CheckBox x:Name="cbCamAdjust" Margin="0,5,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Disable camera auto rotate on movement" ToolTip="Disables the annoying automatic camera adjustment on movement. Intended for mouse users" Checked="CbCamAdjust_Check_Handler" Unchecked="CbCamAdjust_Check_Handler" TabIndex="12" /> <CheckBox x:Name="cbCamAdjust" Margin="0,5,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Disable camera auto rotate on movement" ToolTip="Disables the annoying automatic camera adjustment on movement. Intended for mouse users" Checked="CbCamAdjust_Check_Handler" Unchecked="CbCamAdjust_Check_Handler" TabIndex="12" />
<CheckBox x:Name="cbCamReset" Margin="0,3,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Disable camera reset on lock-on" ToolTip="Disables the annoying camera centering on lock-on when there is no target" Checked="CbCamReset_Check_Handler" Unchecked="CbCamReset_Check_Handler" TabIndex="13" /> <CheckBox x:Name="cbCamReset" Margin="0,3,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Disable camera reset on lock-on" ToolTip="Disables the annoying camera centering on lock-on when there is no target" Checked="CbCamReset_Check_Handler" Unchecked="CbCamReset_Check_Handler" TabIndex="13" />

View file

@ -33,7 +33,6 @@ namespace SekiroFpsUnlockAndMore
internal long _offset_dragonrot_routine = 0x0; internal long _offset_dragonrot_routine = 0x0;
internal long _offset_deathpenalties1 = 0x0; internal long _offset_deathpenalties1 = 0x0;
internal long _offset_deathpenalties2 = 0x0; internal long _offset_deathpenalties2 = 0x0;
internal long _offset_deathpenalties3 = 0x0;
internal long _offset_deathscounter_routine = 0x0; internal long _offset_deathscounter_routine = 0x0;
internal long _offset_timescale = 0x0; internal long _offset_timescale = 0x0;
internal long _offset_timescale_player = 0x0; internal long _offset_timescale_player = 0x0;
@ -41,7 +40,6 @@ namespace SekiroFpsUnlockAndMore
internal byte[] _patch_deathpenalties1_enable; internal byte[] _patch_deathpenalties1_enable;
internal byte[] _patch_deathpenalties2_enable; internal byte[] _patch_deathpenalties2_enable;
internal byte[] _patch_deathpenalties3_enable;
internal MemoryCaveGenerator _memoryCaveGenerator; internal MemoryCaveGenerator _memoryCaveGenerator;
internal SettingsService _settingsService; internal SettingsService _settingsService;
@ -67,7 +65,6 @@ namespace SekiroFpsUnlockAndMore
internal string _path_killsLog; internal string _path_killsLog;
internal RECT _windowRect; internal RECT _windowRect;
internal Size _screenSize; internal Size _screenSize;
internal bool _isLegacyVersion = false;
internal const string _DATACAVE_SPEEDFIX_POINTER = "speedfixPointer"; internal const string _DATACAVE_SPEEDFIX_POINTER = "speedfixPointer";
internal const string _DATACAVE_FOV_POINTER = "fovPointer"; internal const string _DATACAVE_FOV_POINTER = "fovPointer";
@ -96,25 +93,6 @@ namespace SekiroFpsUnlockAndMore
} }
GC.KeepAlive(mutex); GC.KeepAlive(mutex);
try
{
HIGHCONTRAST highContrastInfo = new HIGHCONTRAST();
highContrastInfo.cbSize = Marshal.SizeOf(typeof(HIGHCONTRAST));
if (SystemParametersInfo(SPI_GETHIGHCONTRAST, (uint)highContrastInfo.cbSize, ref highContrastInfo, 0))
{
if ((highContrastInfo.dwFlags & HCF_HIGHCONTRASTON) == 1)
{
// high contrast mode is active, remove grid background color and let the OS handle it
gMainGrid.Background = null;
gSubGrid1.Background = null;
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Could not fetch SystemParameters: " + ex.Message);
}
_path_logs = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.log"; _path_logs = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.log";
_path_deathsLog = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\DeathCounter.txt"; _path_deathsLog = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\DeathCounter.txt";
_path_killsLog = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\TotalKillsCounter.txt"; _path_killsLog = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\TotalKillsCounter.txt";
@ -362,24 +340,12 @@ namespace SekiroFpsUnlockAndMore
} }
string gameFileVersion = FileVersionInfo.GetVersionInfo(procList[0].MainModule.FileName).FileVersion; string gameFileVersion = FileVersionInfo.GetVersionInfo(procList[0].MainModule.FileName).FileVersion;
if (gameFileVersion != GameData.PROCESS_EXE_VERSION) if (gameFileVersion != GameData.PROCESS_EXE_VERSION && Array.IndexOf(GameData.PROCESS_EXE_VERSION_SUPPORTED, gameFileVersion) < 0 && !_settingsService.ApplicationSettings.gameVersionNotify)
{
if (Array.IndexOf(GameData.PROCESS_EXE_VERSION_SUPPORTED_LEGACY, gameFileVersion) < 0)
{
if (!_settingsService.ApplicationSettings.gameVersionNotify)
{ {
MessageBox.Show(string.Format("Unknown game version '{0}'.\nSome functions might not work properly or even crash the game. " + MessageBox.Show(string.Format("Unknown game version '{0}'.\nSome functions might not work properly or even crash the game. " +
"Check for updates on this utility regularly following the link at the bottom.", gameFileVersion), "Sekiro FPS Unlocker and more", MessageBoxButton.OK, MessageBoxImage.Warning); "Check for updates on this utility regularly following the link at the bottom.", gameFileVersion), "Sekiro FPS Unlocker and more", MessageBoxButton.OK, MessageBoxImage.Warning);
ClearConfiguration(); ClearConfiguration();
_settingsService.ApplicationSettings.gameVersionNotify = true; _settingsService.ApplicationSettings.gameVersionNotify = true;
SaveConfiguration();
}
}
else
{
_isLegacyVersion = true;
_settingsService.ApplicationSettings.gameVersionNotify = false;
}
} }
else else
_settingsService.ApplicationSettings.gameVersionNotify = false; _settingsService.ApplicationSettings.gameVersionNotify = false;
@ -536,36 +502,15 @@ namespace SekiroFpsUnlockAndMore
Debug.WriteLine("deathPenalties1 original instruction set: " + BitConverter.ToString(_patch_deathpenalties1_enable).Replace('-', ' ')); Debug.WriteLine("deathPenalties1 original instruction set: " + BitConverter.ToString(_patch_deathpenalties1_enable).Replace('-', ' '));
if (_patch_deathpenalties1_enable != null) if (_patch_deathpenalties1_enable != null)
{ {
if (!_isLegacyVersion)
_offset_deathpenalties2 = patternScan.FindPattern(GameData.PATTERN_DEATHPENALTIES2) + GameData.PATTERN_DEATHPENALTIES2_OFFSET; _offset_deathpenalties2 = patternScan.FindPattern(GameData.PATTERN_DEATHPENALTIES2) + GameData.PATTERN_DEATHPENALTIES2_OFFSET;
else
_offset_deathpenalties2 = patternScan.FindPattern(GameData.PATTERN_DEATHPENALTIES2_LEGACY) + GameData.PATTERN_DEATHPENALTIES2_OFFSET_LEGACY;
Debug.WriteLine("lpDeathPenalties2 found at: 0x" + _offset_deathpenalties2.ToString("X")); Debug.WriteLine("lpDeathPenalties2 found at: 0x" + _offset_deathpenalties2.ToString("X"));
if (IsValidAddress(_offset_deathpenalties2)) if (IsValidAddress(_offset_deathpenalties2))
{ {
ulong instrLength = (ulong)GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH;
if (!_isLegacyVersion)
_patch_deathpenalties2_enable = new byte[GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH]; _patch_deathpenalties2_enable = new byte[GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH];
else if (!ReadProcessMemory(_gameAccessHwnd, _offset_deathpenalties2, _patch_deathpenalties2_enable, (ulong) GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH, out lpNumberOfBytesRead) || lpNumberOfBytesRead.ToInt32() != GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH)
{
_patch_deathpenalties2_enable = new byte[GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH_LEGACY];
instrLength = (ulong)GameData.PATCH_DEATHPENALTIES2_INSTRUCTION_LENGTH_LEGACY;
}
if (!ReadProcessMemory(_gameAccessHwnd, _offset_deathpenalties2, _patch_deathpenalties2_enable, instrLength, out lpNumberOfBytesRead) || lpNumberOfBytesRead.ToInt32() != (long)instrLength)
_patch_deathpenalties2_enable = null; _patch_deathpenalties2_enable = null;
else else
{
Debug.WriteLine("deathPenalties2 original instruction set: " + BitConverter.ToString(_patch_deathpenalties2_enable).Replace('-', ' ')); Debug.WriteLine("deathPenalties2 original instruction set: " + BitConverter.ToString(_patch_deathpenalties2_enable).Replace('-', ' '));
if (!_isLegacyVersion)
{
_offset_deathpenalties3 = _offset_deathpenalties2 + GameData.PATTERN_DEATHPENALTIES3_OFFSET;
_patch_deathpenalties3_enable = new byte[GameData.PATCH_DEATHPENALTIES3_INSTRUCTION_LENGTH];
if (!ReadProcessMemory(_gameAccessHwnd, _offset_deathpenalties3, _patch_deathpenalties3_enable, (ulong)GameData.PATCH_DEATHPENALTIES3_INSTRUCTION_LENGTH, out lpNumberOfBytesRead) || lpNumberOfBytesRead.ToInt32() != GameData.PATCH_DEATHPENALTIES3_INSTRUCTION_LENGTH)
_patch_deathpenalties2_enable = null;
else
Debug.WriteLine("deathPenalties3 original instruction set: " + BitConverter.ToString(_patch_deathpenalties3_enable).Replace('-', ' '));
}
}
} }
else else
_offset_deathpenalties2 = 0x0; _offset_deathpenalties2 = 0x0;
@ -575,10 +520,8 @@ namespace SekiroFpsUnlockAndMore
{ {
_offset_deathpenalties1 = 0x0; _offset_deathpenalties1 = 0x0;
_offset_deathpenalties2 = 0x0; _offset_deathpenalties2 = 0x0;
_offset_deathpenalties3 = 0x0;
_patch_deathpenalties1_enable = null; _patch_deathpenalties1_enable = null;
_patch_deathpenalties2_enable = null; _patch_deathpenalties2_enable = null;
_patch_deathpenalties3_enable = null;
} }
if (_settingsService.ApplicationSettings.hiddenDPs == ZUH_HIDDEN_DP) if (_settingsService.ApplicationSettings.hiddenDPs == ZUH_HIDDEN_DP)
@ -1124,17 +1067,13 @@ namespace SekiroFpsUnlockAndMore
{ {
WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties1, GameData.PATCH_DEATHPENALTIES1_DISABLE); WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties1, GameData.PATCH_DEATHPENALTIES1_DISABLE);
WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties2, GameData.PATCH_DEATHPENALTIES2_DISABLE); WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties2, GameData.PATCH_DEATHPENALTIES2_DISABLE);
if (!_isLegacyVersion && _offset_deathpenalties3 != 0x0)
WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties3, GameData.PATCH_DEATHPENALTIES3_DISABLE);
} }
else if (this.cbDeathPenalty.IsChecked == false) else if (this.cbDeathPenalty.IsChecked == false)
{ {
if (!_initialStartup) if (_initialStartup)
{ {
WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties1, _patch_deathpenalties1_enable); WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties1, _patch_deathpenalties1_enable);
WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties2, _patch_deathpenalties2_enable); WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties2, _patch_deathpenalties2_enable);
if (!_isLegacyVersion && _offset_deathpenalties3 != 0x0)
WriteBytes(_gameAccessHwndStatic, _offset_deathpenalties3, _patch_deathpenalties3_enable);
} }
if (showStatus) UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White); if (showStatus) UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
return false; return false;
@ -1680,9 +1619,7 @@ namespace SekiroFpsUnlockAndMore
} }
catch (Exception ex) catch (Exception ex)
{ {
LogToFile("Failed writing stats file: " + ex.Message); MessageBox.Show("Failed writing stats file: " + ex.Message, "Sekiro Fps Unlock And More");
// don't show a messagebox as this will potentially steal focus from game
//MessageBox.Show("Failed writing stats file: " + ex.Message, "Sekiro Fps Unlock And More");
} }
} }
@ -1936,8 +1873,6 @@ namespace SekiroFpsUnlockAndMore
private const uint SWP_FRAMECHANGED = 0x0020; private const uint SWP_FRAMECHANGED = 0x0020;
private const uint SWP_SHOWWINDOW = 0x0040; private const uint SWP_SHOWWINDOW = 0x0040;
private const int ZUH_HIDDEN_DP = 0x7; private const int ZUH_HIDDEN_DP = 0x7;
private const uint SPI_GETHIGHCONTRAST = 0x0042;
private const int HCF_HIGHCONTRASTON = 0x00000001;
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern Boolean RegisterHotKey(IntPtr hWnd, Int32 id, UInt32 fsModifiers, UInt32 vlc); public static extern Boolean RegisterHotKey(IntPtr hWnd, Int32 id, UInt32 fsModifiers, UInt32 vlc);
@ -1954,18 +1889,6 @@ namespace SekiroFpsUnlockAndMore
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
private static extern Boolean CloseHandle(IntPtr hObject); private static extern Boolean CloseHandle(IntPtr hObject);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct HIGHCONTRAST
{
public int cbSize;
public int dwFlags;
public IntPtr lpszDefaultScheme;
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, ref HIGHCONTRAST pvParam, UInt32 fWinIni);
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, Int32 nIndex); private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, Int32 nIndex);

View file

@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("uberhalit")] [assembly: AssemblyCompany("uberhalit")]
[assembly: AssemblyProduct("SekiroFpsUnlockAndMore")] [assembly: AssemblyProduct("SekiroFpsUnlockAndMore")]
[assembly: AssemblyCopyright("Copyright © uberhalit 2020")] [assembly: AssemblyCopyright("Copyright © uberhalit 2019")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
@ -18,5 +18,5 @@ using System.Runtime.InteropServices;
ResourceDictionaryLocation.SourceAssembly ResourceDictionaryLocation.SourceAssembly
)] )]
[assembly: AssemblyVersion("1.2.5.2")] [assembly: AssemblyVersion("1.2.5.0")]
[assembly: AssemblyFileVersion("1.2.5.2")] [assembly: AssemblyFileVersion("1.2.5.0")]