mirror of
https://github.com/uberhalit/SekiroFpsUnlockAndMore.git
synced 2026-06-13 09:57:55 +00:00
initial version
This commit is contained in:
parent
44263f2c72
commit
e01a01822c
16 changed files with 1275 additions and 0 deletions
6
SekiroFpsUnlockAndMore/App.config
Normal file
6
SekiroFpsUnlockAndMore/App.config
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
9
SekiroFpsUnlockAndMore/App.xaml
Normal file
9
SekiroFpsUnlockAndMore/App.xaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<Application x:Class="SekiroFpsUnlockAndMore.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:SekiroFpsUnlockAndMore"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
17
SekiroFpsUnlockAndMore/App.xaml.cs
Normal file
17
SekiroFpsUnlockAndMore/App.xaml.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace SekiroFpsUnlockAndMore
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaktionslogik für "App.xaml"
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
49
SekiroFpsUnlockAndMore/MainWindow.xaml
Normal file
49
SekiroFpsUnlockAndMore/MainWindow.xaml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<Window x:Class="SekiroFpsUnlockAndMore.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SekiroFpsUnlockAndMore"
|
||||
mc:Ignorable="d"
|
||||
Title="Sekiro FPS Unlocker and more v1.0.0" Height="530" Width="306" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing">
|
||||
|
||||
<Grid>
|
||||
<CheckBox x:Name="cbUnlockFps" Content="FPS lock (0= unlimited):" IsChecked="True" HorizontalAlignment="Left" Margin="10,12,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||
<TextBox x:Name="tbFps" Text="144" MaxLength="3" HorizontalAlignment="Left" Height="25" Margin="181,10,0,0" VerticalAlignment="Top" Width="106" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler"/>
|
||||
<CheckBox x:Name="cbAddWidescreen" Content="Add custom resolution:" HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||
<TextBox x:Name="tbWidth" Text="2560" MaxLength="4" HorizontalAlignment="Left" Height="25" Margin="181,40,0,0" VerticalAlignment="Top" Width="45" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||
<Label Content="x" HorizontalAlignment="Left" Margin="226,36,0,0" VerticalAlignment="Top" FontSize="14 px"/>
|
||||
<TextBox x:Name="tbHeight" Text="1080" MaxLength="4" HorizontalAlignment="Left" Height="25" Margin="242,40,0,0" VerticalAlignment="Top" Width="45" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||
<CheckBox x:Name="cbFov" Content="Increase FOV by:" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||
<ComboBox x:Name="cbSelectFov" HorizontalAlignment="Left" VerticalAlignment="Top" Width="106" Height="25" Margin="181,70,0,0" FontSize="14 px" SelectedValuePath="Key" DisplayMemberPath="Value"/>
|
||||
<CheckBox x:Name="cbBorderless" Content="Borderless window mode" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||
<Button x:Name="bPatch" Content="Patch game (CTRL + P)" FontSize="14 px" HorizontalAlignment="Left" Margin="10,125,0,0" VerticalAlignment="Top" Width="277" Height="30"
|
||||
BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Focusable="False" Click="BPatch_Click" />
|
||||
<TextBox x:Name="tbStatus" Text="waiting for game..." TextAlignment="Center" HorizontalAlignment="Left" TextWrapping="NoWrap" Height="25" Margin="10,165,0,0" VerticalAlignment="Top" Width="277" FontSize="14 px" IsEnabled="False" FontWeight="Bold" />
|
||||
<StackPanel HorizontalAlignment="Left" Height="305" Margin="13,195,0,0" VerticalAlignment="Top" Width="275">
|
||||
<TextBlock HorizontalAlignment="Left" TextWrapping="WrapWithOverflow" VerticalAlignment="Top" FontSize="11 px" IsEnabled="False">
|
||||
<TextBlock.Inlines>
|
||||
<Run FontWeight="Bold">If your monitor is 60 Hz you will have to use</Run>
|
||||
<Run FontWeight="Bold" Foreground="#FFF00000">fullscreen mode and force disable VSYNC</Run>
|
||||
<Run FontWeight="Bold">with Nvidia Control panel or AMD Radeon Settings to get frame rate unlock working.</Run>
|
||||
<Run>To avoid stuttering it's recommended to disable VSYNC even with a 144 Hz monitor.</Run>
|
||||
<Run FontWeight="Bold">If your monitor is >60 Hz you will have to use</Run>
|
||||
<Run FontWeight="Bold" Foreground="#FFF00000">borderless window mode or force the game to run on highest available refresh rate</Run>
|
||||
<Run FontWeight="Bold">using Nvidia Control panel or AMD Radeon Settings.</Run>
|
||||
<Run>Borderless window mode requires "Window mode" in game settings first.</Run>
|
||||
<Run FontWeight="Bold">Custom resolution adds 21/9 support and overwrites default 1920x1080 resolution, hud will be limited to 16/9 though.</Run>
|
||||
<Run>Borderless window mode with custom resolution requires you to patch and set resolution first, then add borderless patch afterwards.</Run>
|
||||
<Run FontWeight="Bold">For FOV patch to work you need to be ingame.</Run>
|
||||
<Run>FOV patch resets after save game reload.</Run>
|
||||
<Run FontWeight="Bold" Foreground="#FFF00000">See the link below for detailed information, GSYNC support and an AMD fix.</Run>
|
||||
</TextBlock.Inlines>
|
||||
</TextBlock>
|
||||
|
||||
<Label HorizontalAlignment="Right" VerticalAlignment="Top" FontSize="12 px">
|
||||
<Hyperlink NavigateUri="https://github.com/uberhalit/SekiroFpsUnlockAndMore" RequestNavigate="Hyperlink_RequestNavigate">
|
||||
v1.0.0 - by uberhalit
|
||||
</Hyperlink>
|
||||
</Label>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
600
SekiroFpsUnlockAndMore/MainWindow.xaml.cs
Normal file
600
SekiroFpsUnlockAndMore/MainWindow.xaml.cs
Normal file
|
|
@ -0,0 +1,600 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SekiroFpsUnlockAndMore
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
internal const string PROCESS_NAME = "sekiro";
|
||||
internal const string PROCESS_TITLE = "Sekiro";
|
||||
internal const string PROCESS_DESCRIPTION = "Shadows Die Twice";
|
||||
|
||||
internal const string PATTERN_FRAMELOCK = "00 88 88 3C 4C 89 AB 00"; // ?? 88 88 3C 4C 89 AB ?? // pattern/signature of frame rate limiter, first byte (last in mem) can can be 88/90 instead of 89 due to precision loss on floating point numbers
|
||||
internal const string PATTERN_FRAMELOCK_MASK = "?xxxxxx?"; // mask for frame rate limiter signature scanning
|
||||
internal const string PATTERN_FRAMELOCK_LONG = "44 88 6B 00 C7 43 00 89 88 88 3C 4C 89 AB 00 00 00 00"; // 44 88 6B ?? C7 43 ?? 89 88 88 3C 4C 89 AB ?? ?? ?? ??
|
||||
internal const string PATTERN_FRAMELOCK_LONG_MASK = "xxx?xx?xxxxxxx????";
|
||||
internal const int PATTERN_FRAMELOCK_LONG_OFFSET = 7;
|
||||
internal const string PATTERN_FRAMELOCK_FUZZY = "C7 43 00 00 00 00 00 4C 89 AB 00 00 00 00"; // C7 43 ?? ?? ?? ?? ?? 4C 89 AB ?? ?? ?? ??
|
||||
internal const string PATTERN_FRAMELOCK_FUZZY_MASK = "xx?????xxx????";
|
||||
internal const int PATTERN_FRAMELOCK_FUZZY_OFFSET = 3; // offset to byte array from found position
|
||||
internal const string PATTERN_FRAMELOCK_RUNNING_FIX = "F3 0F 59 05 00 30 92 02 0F 2F F8"; // F3 0F 59 05 ?? 30 92 02 0F 2F F8 | 0F 51 C2 F3 0F 59 05 ?? ?? ?? ?? 0F 2F F8
|
||||
internal const string PATTERN_FRAMELOCK_RUNNING_FIX_MASK = "xxxx?xxxxxx";
|
||||
internal const int PATTERN_FRAMELOCK_RUNNING_FIX_OFFSET = 4;
|
||||
internal const string PATTERN_RESOLUTION = "80 07 00 00 38 04"; // 1920x1080
|
||||
internal const string PATTERN_RESOLUTION_MASK = "xxxxxx";
|
||||
internal const string PATTERN_WIDESCREEN_219 = "00 47 47 8B 94 C7 1C 02 00 00"; // ?? 47 47 8B 94 C7 1C 02 00 00
|
||||
internal const string PATTERN_WIDESCREEN_219_MASK = "?xxxxxxxxx";
|
||||
internal byte[] PATCH_FRAMERATE_RUNNING_FIX_DISABLE = new byte[1] { 0x90 };
|
||||
internal byte[] PATCH_FRAMERATE_UNLIMITED = new byte[4] { 0x00, 0x00, 0x00, 0x00 };
|
||||
internal byte[] PATCH_WIDESCREEN_219_DISABLE = new byte[1] { 0x74 };
|
||||
internal byte[] PATCH_WIDESCREEN_219_ENABLE = new byte[1] { 0xEB };
|
||||
internal byte[] PATCH_FOV_DISABLE = new byte[1] { 0x0C };
|
||||
|
||||
// credits to jackfuste for FOV findings
|
||||
internal const string PATTERN_FOVSETTING = "F3 0F 10 08 F3 0F 59 0D 00 E7 9B 02"; // F3 0F 10 08 F3 0F 59 0D ?? E7 9B 02
|
||||
internal const string PATTERN_FOVSETTING_MASK = "xxxxxxxx?xxx";
|
||||
internal const int PATTERN_FOVSETTING_OFFSET = 8;
|
||||
internal Dictionary<byte, string> _fovMatrix = new Dictionary<byte, string>
|
||||
{
|
||||
{ 0x10, "+ 15%" },
|
||||
{ 0x14, "+ 40%" },
|
||||
{ 0x18, "+ 75%" },
|
||||
{ 0x1C, "+ 90%" },
|
||||
};
|
||||
|
||||
internal long _offset_framelock = 0x0;
|
||||
internal long _offset_framelock_running_fix = 0x0;
|
||||
internal long _offset_resolution = 0x0;
|
||||
internal long _offset_widescreen_219 = 0x0;
|
||||
internal long _offset_fovsetting = 0x0;
|
||||
internal bool _running = false;
|
||||
internal Process _game;
|
||||
internal IntPtr _gameHwnd = IntPtr.Zero;
|
||||
internal IntPtr _gameProc = IntPtr.Zero;
|
||||
internal static IntPtr _gameProcStatic;
|
||||
internal readonly DispatcherTimer _dispatcherTimerCheck = new DispatcherTimer();
|
||||
internal string logPath;
|
||||
internal bool retryAccess = true;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On window loaded.
|
||||
/// </summary>
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
logPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.log";
|
||||
|
||||
this.cbSelectFov.ItemsSource = _fovMatrix;
|
||||
this.cbSelectFov.SelectedIndex = 0;
|
||||
|
||||
IntPtr hwnd = new WindowInteropHelper(this).Handle;
|
||||
if (!RegisterHotKey(hwnd, 9009, MOD_CONTROL, VK_P))
|
||||
MessageBox.Show("Hotkey is already in use, it may not work.", "Sekiro FPS Unlocker and more");
|
||||
|
||||
// add a hook for WindowsMessageQueue to recognize hotkey-press
|
||||
ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
|
||||
|
||||
_dispatcherTimerCheck.Tick += new EventHandler(CheckGame);
|
||||
_dispatcherTimerCheck.Interval = new TimeSpan(0, 0, 0, 3);
|
||||
_dispatcherTimerCheck.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On window closing.
|
||||
/// </summary>
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
ComponentDispatcher.ThreadFilterMessage -= ComponentDispatcherThreadFilterMessage;
|
||||
IntPtr hwnd = new WindowInteropHelper(this).Handle;
|
||||
UnregisterHotKey(hwnd, 9009);
|
||||
if (_gameProc != IntPtr.Zero)
|
||||
CloseHandle(_gameProc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Windows Message queue (Wndproc) to catch HotKeyPressed
|
||||
/// </summary>
|
||||
private void ComponentDispatcherThreadFilterMessage(ref MSG msg, ref bool handled)
|
||||
{
|
||||
if (!handled)
|
||||
{
|
||||
if (msg.message == WM_HOTKEY_MSG_ID) // hotkeyevent
|
||||
{
|
||||
if (msg.wParam.ToInt32() == 9009) // patch game
|
||||
{
|
||||
handled = true;
|
||||
PatchGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if game is running and initializes further functionality.
|
||||
/// </summary>
|
||||
private void CheckGame(object sender, EventArgs e)
|
||||
{
|
||||
Process[] procList = Process.GetProcessesByName(PROCESS_NAME);
|
||||
if (procList.Length < 1)
|
||||
return;
|
||||
|
||||
if (_running || _offset_framelock != 0x0)
|
||||
return;
|
||||
|
||||
int gameIndex = -1;
|
||||
for (int i = 0; i < procList.Length; i++)
|
||||
{
|
||||
if (procList[i].MainWindowTitle == PROCESS_TITLE && procList[i].MainModule.FileVersionInfo.FileDescription.Contains(PROCESS_DESCRIPTION))
|
||||
{
|
||||
gameIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gameIndex < 0)
|
||||
{
|
||||
UpdateStatus("no valid game process found...", Brushes.Red);
|
||||
LogToFile("no valid game process found...");
|
||||
for (int j = 0; j < procList.Length; j++)
|
||||
{
|
||||
LogToFile(string.Format("\tProcess #{0}: '{1}' | ({2})", j, procList[j].MainModule.FileName, procList[j].MainModule.FileVersionInfo.FileName));
|
||||
LogToFile(string.Format("\tDescription #{0}: {1} | {2} | {3}", j, procList[j].MainWindowTitle, procList[j].MainModule.FileVersionInfo.CompanyName, procList[j].MainModule.FileVersionInfo.FileDescription));
|
||||
LogToFile(string.Format("\tData #{0}: {1} | {2} | {3} | {4} | {5}", j, procList[j].MainModule.FileVersionInfo.FileVersion, procList[j].MainModule.ModuleMemorySize, procList[j].StartTime, procList[j].Responding, procList[j].HasExited));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_game = procList[gameIndex];
|
||||
_gameHwnd = procList[gameIndex].MainWindowHandle;
|
||||
_gameProc = OpenProcess(PROCESS_ALL_ACCESS, false, (uint)procList[gameIndex].Id);
|
||||
_gameProcStatic = _gameProc;
|
||||
if (_gameHwnd == IntPtr.Zero || _gameProc == IntPtr.Zero || procList[gameIndex].MainModule.BaseAddress == IntPtr.Zero)
|
||||
{
|
||||
LogToFile("no access to game...");
|
||||
LogToFile("Hwnd: " + _gameHwnd.ToString("X"));
|
||||
LogToFile("Proc: " + _gameProc.ToString("X"));
|
||||
LogToFile("Base: " + procList[gameIndex].MainModule.BaseAddress.ToString("X"));
|
||||
if (!retryAccess)
|
||||
{
|
||||
UpdateStatus("no access to game...", Brushes.Red);
|
||||
_dispatcherTimerCheck.Stop();
|
||||
return;
|
||||
}
|
||||
_gameHwnd = IntPtr.Zero;
|
||||
if (_gameProc != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(_gameProc);
|
||||
_gameProc = IntPtr.Zero;
|
||||
_gameProcStatic = IntPtr.Zero;
|
||||
}
|
||||
LogToFile("retrying...");
|
||||
retryAccess = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//string gameFileVersion = FileVersionInfo.GetVersionInfo(procList[0].MainModule.FileName).FileVersion;
|
||||
|
||||
_offset_framelock = PatternScan.FindPattern(_gameProc, procList[gameIndex].MainModule, PATTERN_FRAMELOCK, PATTERN_FRAMELOCK_MASK, ' ');
|
||||
Debug.WriteLine("1. Framelock found at: 0x" + _offset_framelock.ToString("X"));
|
||||
if (!IsValid(_offset_framelock))
|
||||
{
|
||||
_offset_framelock = PatternScan.FindPattern(_gameProc, procList[gameIndex].MainModule, PATTERN_FRAMELOCK_FUZZY, PATTERN_FRAMELOCK_FUZZY_MASK, ' ') + PATTERN_FRAMELOCK_FUZZY_OFFSET;
|
||||
Debug.WriteLine("2. Framelock found at: 0x" + _offset_framelock.ToString("X"));
|
||||
}
|
||||
if (!IsValid(_offset_framelock))
|
||||
{
|
||||
UpdateStatus("framelock not found...", Brushes.Red);
|
||||
LogToFile("framelock not found...");
|
||||
this.cbUnlockFps.IsEnabled = false;
|
||||
this.cbUnlockFps.IsChecked = false;
|
||||
}
|
||||
_offset_framelock_running_fix = PatternScan.FindPattern(_gameProc, procList[gameIndex].MainModule, PATTERN_FRAMELOCK_RUNNING_FIX, PATTERN_FRAMELOCK_RUNNING_FIX_MASK, ' ') + PATTERN_FRAMELOCK_RUNNING_FIX_OFFSET;
|
||||
Debug.WriteLine("Running fix found at: 0x" + _offset_framelock_running_fix.ToString("X"));
|
||||
if (!IsValid(_offset_framelock_running_fix))
|
||||
{
|
||||
UpdateStatus("running fix not found...", Brushes.Red);
|
||||
LogToFile("running fix not found...");
|
||||
this.cbAddWidescreen.IsEnabled = false;
|
||||
this.cbAddWidescreen.IsChecked = false;
|
||||
}
|
||||
|
||||
_offset_resolution = PatternScan.FindPattern(_gameProc, procList[gameIndex].MainModule, PATTERN_RESOLUTION, PATTERN_RESOLUTION_MASK, ' ');
|
||||
Debug.WriteLine("Resolution found at: 0x" + _offset_resolution.ToString("X"));
|
||||
if (!IsValid(_offset_resolution))
|
||||
{
|
||||
UpdateStatus("resolution not found...", Brushes.Red);
|
||||
LogToFile("resolution not found...");
|
||||
this.cbAddWidescreen.IsEnabled = false;
|
||||
this.cbAddWidescreen.IsChecked = false;
|
||||
}
|
||||
_offset_widescreen_219 = PatternScan.FindPattern(_gameProc, procList[gameIndex].MainModule, PATTERN_WIDESCREEN_219, PATTERN_WIDESCREEN_219_MASK, ' ');
|
||||
Debug.WriteLine("Widescreen 21/9 found at: 0x" + _offset_widescreen_219.ToString("X"));
|
||||
if (!IsValid(_offset_widescreen_219))
|
||||
{
|
||||
UpdateStatus("widescreen 21/9 not found...", Brushes.Red);
|
||||
LogToFile("Widescreen 21/9 not found...");
|
||||
this.cbAddWidescreen.IsEnabled = false;
|
||||
this.cbAddWidescreen.IsChecked = false;
|
||||
}
|
||||
|
||||
_offset_fovsetting = PatternScan.FindPattern(_gameProc, procList[gameIndex].MainModule, PATTERN_FOVSETTING, PATTERN_FOVSETTING_MASK, ' ') + PATTERN_FOVSETTING_OFFSET;
|
||||
Debug.WriteLine("FOV found at: 0x" + _offset_fovsetting.ToString("X"));
|
||||
if (!IsValid(_offset_fovsetting))
|
||||
{
|
||||
UpdateStatus("FOV not found...", Brushes.Red);
|
||||
LogToFile("FOV not found...");
|
||||
this.cbFov.IsEnabled = false;
|
||||
this.cbFov.IsChecked = false;
|
||||
}
|
||||
|
||||
_running = true;
|
||||
_dispatcherTimerCheck.Stop();
|
||||
PatchGame();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Patch up this broken port
|
||||
/// </summary>
|
||||
private void PatchGame()
|
||||
{
|
||||
if (!_running)
|
||||
return;
|
||||
|
||||
if (_game.HasExited)
|
||||
{
|
||||
_running = false;
|
||||
_gameHwnd = IntPtr.Zero;
|
||||
_gameProc = IntPtr.Zero;
|
||||
_gameProcStatic = IntPtr.Zero;
|
||||
_offset_framelock = 0x0;
|
||||
_offset_framelock_running_fix = 0x0;
|
||||
_offset_resolution = 0x0;
|
||||
_offset_widescreen_219 = 0x0;
|
||||
_offset_fovsetting = 0x0;
|
||||
UpdateStatus("waiting for game...", Brushes.White);
|
||||
_dispatcherTimerCheck.Start();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.cbUnlockFps.IsChecked == true)
|
||||
{
|
||||
int fps = -1;
|
||||
bool isNumber = Int32.TryParse(this.tbFps.Text, out fps);
|
||||
if (fps < 0 || !isNumber)
|
||||
{
|
||||
this.tbFps.Text = "60";
|
||||
fps = 60;
|
||||
}
|
||||
else if (fps > 0 && fps < 30)
|
||||
{
|
||||
this.tbFps.Text = "30";
|
||||
fps = 30;
|
||||
}
|
||||
else if (fps > 300)
|
||||
{
|
||||
this.tbFps.Text = "300";
|
||||
fps = 300;
|
||||
}
|
||||
|
||||
if (fps == 0)
|
||||
{
|
||||
WriteBytes(_gameProcStatic, _offset_framelock, PATCH_FRAMERATE_UNLIMITED);
|
||||
WriteBytes(_gameProcStatic, _offset_framelock_running_fix, new byte[1] { 0xF8 }); // F8 is maximum
|
||||
}
|
||||
else
|
||||
{
|
||||
int speed = 144 + (int)Math.Ceiling((fps - 60) / 16f) * 8; // calculation from game functions
|
||||
if (speed > 248)
|
||||
speed = 248;
|
||||
float deltaTime = (1000f / fps) / 1000f;
|
||||
Debug.WriteLine("Deltatime hex: 0x" + getHexRepresentationFromFloat(deltaTime));
|
||||
Debug.WriteLine("Speed hex: 0x" + speed.ToString("X"));
|
||||
WriteBytes(_gameProcStatic, _offset_framelock, BitConverter.GetBytes(deltaTime));
|
||||
WriteBytes(_gameProcStatic, _offset_framelock_running_fix, new byte[] { (byte)Convert.ToInt16(speed) });
|
||||
}
|
||||
}
|
||||
else if (this.cbUnlockFps.IsChecked == false)
|
||||
{
|
||||
float deltaTime = (1000f / 60) / 1000f;
|
||||
WriteBytes(_gameProcStatic, _offset_framelock, BitConverter.GetBytes(deltaTime));
|
||||
WriteBytes(_gameProcStatic, _offset_framelock_running_fix, PATCH_FRAMERATE_RUNNING_FIX_DISABLE);
|
||||
}
|
||||
|
||||
if (this.cbAddWidescreen.IsChecked == true)
|
||||
{
|
||||
int width = -1;
|
||||
bool isNumber = Int32.TryParse(this.tbWidth.Text, out width);
|
||||
if (width < 800 || !isNumber)
|
||||
{
|
||||
this.tbWidth.Text = "2560";
|
||||
width = 2560;
|
||||
}
|
||||
else if (width > 5760)
|
||||
{
|
||||
this.tbWidth.Text = "5760";
|
||||
width = 5760;
|
||||
}
|
||||
int height = -1;
|
||||
isNumber = Int32.TryParse(this.tbHeight.Text, out height);
|
||||
if (height < 450 || !isNumber)
|
||||
{
|
||||
this.tbHeight.Text = "1080";
|
||||
height = 1080;
|
||||
}
|
||||
else if (height > 2160)
|
||||
{
|
||||
this.tbHeight.Text = "2160";
|
||||
height = 2160;
|
||||
}
|
||||
WriteBytes(_gameProcStatic, _offset_resolution, BitConverter.GetBytes(width));
|
||||
WriteBytes(_gameProcStatic, _offset_resolution + 4, BitConverter.GetBytes(height));
|
||||
WriteBytes(_gameProcStatic, _offset_widescreen_219, (float) width / (float) height > 1.9f ? PATCH_WIDESCREEN_219_ENABLE : PATCH_WIDESCREEN_219_DISABLE);
|
||||
}
|
||||
else if (this.cbAddWidescreen.IsChecked == false)
|
||||
{
|
||||
WriteBytes(_gameProcStatic, _offset_resolution, BitConverter.GetBytes(1920));
|
||||
WriteBytes(_gameProcStatic, _offset_resolution + 4, BitConverter.GetBytes(1080));
|
||||
WriteBytes(_gameProcStatic, _offset_widescreen_219, PATCH_WIDESCREEN_219_DISABLE);
|
||||
}
|
||||
|
||||
if (this.cbFov.IsChecked == true)
|
||||
{
|
||||
byte[] fovByte = new byte[1];
|
||||
fovByte[0] = ((KeyValuePair<byte, string>) this.cbSelectFov.SelectedItem).Key;
|
||||
WriteBytes(_gameProcStatic, _offset_fovsetting, fovByte);
|
||||
}
|
||||
else if (this.cbFov.IsChecked == false)
|
||||
{
|
||||
WriteBytes(_gameProcStatic, _offset_fovsetting, PATCH_FOV_DISABLE);
|
||||
}
|
||||
|
||||
if (this.cbBorderless.IsChecked == true)
|
||||
{
|
||||
if (!IsFullscreen(_gameHwnd))
|
||||
SetWindowBorderless(_gameHwnd);
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please exit fullscreen first before activating borderless window mode.", "Sekiro FPS Unlocker and more");
|
||||
this.cbBorderless.IsChecked = false;
|
||||
}
|
||||
}
|
||||
else if (this.cbBorderless.IsChecked == false && !IsFullscreen(_gameHwnd))
|
||||
{
|
||||
SetWindowWindowed(_gameHwnd);
|
||||
}
|
||||
|
||||
if (this.cbUnlockFps.IsChecked == true || this.cbAddWidescreen.IsChecked == true || this.cbFov.IsChecked == true)
|
||||
UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game patched!", Brushes.Green);
|
||||
else
|
||||
UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
||||
}
|
||||
|
||||
/// <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 string getHexRepresentationFromFloat(float input)
|
||||
{
|
||||
uint f = BitConverter.ToUInt32(BitConverter.GetBytes(input), 0);
|
||||
return "0x" + f.ToString("X8");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if window is in fullscreen mode.
|
||||
/// </summary>
|
||||
/// <param name="hwnd">The main window handle of the window.</param>
|
||||
/// <remarks>
|
||||
/// Fullscreen windows have WS_EX_TOPMOST flag set.
|
||||
/// </remarks>
|
||||
/// <returns>True if window is run in fullscreen mode.</returns>
|
||||
private bool IsFullscreen(IntPtr hwnd)
|
||||
{
|
||||
long wndStyle = GetWindowLongPtr(hwnd, GWL_STYLE).ToInt64();
|
||||
long wndExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE).ToInt64();
|
||||
|
||||
if (wndStyle == 0 || wndExStyle == 0)
|
||||
return false;
|
||||
|
||||
if ((wndExStyle & WS_EX_TOPMOST) == 0)
|
||||
return false;
|
||||
if ((wndStyle & WS_POPUP) != 0)
|
||||
return false;
|
||||
if ((wndStyle & WS_CAPTION) != 0)
|
||||
return false;
|
||||
if ((wndStyle & WS_BORDER) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a window to ordinary windowed mode
|
||||
/// </summary>
|
||||
/// <param name="hwnd">The handle to the window.</param>
|
||||
private void SetWindowWindowed(IntPtr hwnd)
|
||||
{
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, WS_VISIBLE | WS_CAPTION | WS_BORDER | WS_CLIPSIBLINGS | WS_DLGFRAME | WS_SYSMENU | WS_GROUP | WS_MINIMIZEBOX);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a window to borderless windowed mode and moves it to position 0x0.
|
||||
/// </summary>
|
||||
/// <param name="hwnd">The handle to the window.</param>
|
||||
private void SetWindowBorderless(IntPtr hwnd)
|
||||
{
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
|
||||
RECT rect;
|
||||
GetWindowRect(hwnd, out rect);
|
||||
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, rect.Right - rect.Left, rect.Bottom - rect.Top, SWP_FRAMECHANGED | SWP_SHOWWINDOW);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a pointer is valid.
|
||||
/// </summary>
|
||||
/// <param name="address">The address the pointer points to.</param>
|
||||
/// <returns>True if pointer points to a valid address.</returns>
|
||||
private static bool IsValid(Int64 address)
|
||||
{
|
||||
return (address >= 0x10000 && address < 0x000F000000000000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a given type and value to processes memory using a generic method.
|
||||
/// </summary>
|
||||
/// <param name="gameProc">The process handle to read from.</param>
|
||||
/// <param name="lpBaseAddress">The address to write from.</param>
|
||||
/// <param name="bytes">The byte array to write.</param>
|
||||
/// <returns>True if successful, false otherwise.</returns>
|
||||
private static bool WriteBytes(IntPtr gameProc, Int64 lpBaseAddress, byte[] bytes)
|
||||
{
|
||||
IntPtr lpNumberOfBytesWritten;
|
||||
return WriteProcessMemory(gameProc, lpBaseAddress, bytes, (ulong)bytes.Length, out lpNumberOfBytesWritten);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check whether input is numeric only.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to check.</param>
|
||||
/// <returns>True if inout is numeric only.</returns>
|
||||
private bool IsNumericInput(string text)
|
||||
{
|
||||
return Regex.IsMatch(text, "[^0-9]+");
|
||||
}
|
||||
|
||||
private void UpdateStatus(string text, Brush color)
|
||||
{
|
||||
this.tbStatus.Background = color;
|
||||
this.tbStatus.Text = text;
|
||||
}
|
||||
|
||||
private void Numeric_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
e.Handled = IsNumericInput(e.Text);
|
||||
}
|
||||
|
||||
private void Numeric_PastingHandler(object sender, DataObjectPastingEventArgs e)
|
||||
{
|
||||
if (e.DataObject.GetDataPresent(typeof(String)))
|
||||
{
|
||||
String text = (String)e.DataObject.GetData(typeof(String));
|
||||
if (IsNumericInput(text)) e.CancelCommand();
|
||||
}
|
||||
else e.CancelCommand();
|
||||
}
|
||||
|
||||
private void CheckBoxChanged_Handler(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PatchGame();
|
||||
}
|
||||
|
||||
private void BPatch_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PatchGame();
|
||||
}
|
||||
|
||||
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
// log messages to file
|
||||
private void LogToFile(string msg)
|
||||
{
|
||||
string timedMsg = "[" + DateTime.Now + "] " + msg;
|
||||
Debug.WriteLine(timedMsg);
|
||||
try
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(logPath, true))
|
||||
{
|
||||
writer.WriteLine(timedMsg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Writing to log file failed: " + ex.Message, "Sekiro Fps Unlock And More");
|
||||
}
|
||||
}
|
||||
|
||||
#region WINAPI
|
||||
private const int WM_HOTKEY_MSG_ID = 0x0312;
|
||||
private const int MOD_CONTROL = 0x0002;
|
||||
private const uint VK_P = 0x0050;
|
||||
private const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
|
||||
private const int GWL_EXSTYLE = -20;
|
||||
private const int GWL_STYLE = -16;
|
||||
private const uint WS_CLIPSIBLINGS = 0x04000000;
|
||||
private const uint WS_DLGFRAME = 0x00400000;
|
||||
private const uint WS_SYSMENU = 0x00080000;
|
||||
private const uint WS_GROUP = 0x00020000;
|
||||
private const uint WS_MINIMIZEBOX = 0x00020000;
|
||||
private const uint WS_POPUP = 0x80000000;
|
||||
private const uint WS_VISIBLE = 0x10000000;
|
||||
private const uint WS_CAPTION = 0x00C00000;
|
||||
private const uint WS_BORDER = 0x00800000;
|
||||
private const uint WS_EX_TOPMOST = 0x00000008;
|
||||
private const uint WS_EX_WINDOWEDGE = 0x00000100;
|
||||
private const int HWND_NOTOPMOST = -2;
|
||||
private const uint SWP_FRAMECHANGED = 0x0020;
|
||||
private const uint SWP_SHOWWINDOW = 0x0040;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern Boolean RegisterHotKey(IntPtr hWnd, Int32 id, UInt32 fsModifiers, UInt32 vlc);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern Boolean UnregisterHotKey(IntPtr hWnd, Int32 id);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr OpenProcess(
|
||||
UInt32 dwDesiredAccess,
|
||||
Boolean bInheritHandle,
|
||||
UInt32 dwProcessId);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern Boolean CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, Int32 nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
|
||||
private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, Int32 nIndex, Int64 dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
|
||||
public static extern IntPtr SetWindowPos(IntPtr hWnd, Int32 hWndInsertAfter, Int32 X, Int32 Y, Int32 cx, Int32 cy, UInt32 uFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left; // x position of upper-left corner
|
||||
public int Top; // y position of upper-left corner
|
||||
public int Right; // x position of lower-right corner
|
||||
public int Bottom; // y position of lower-right corner
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
internal static extern bool WriteProcessMemory(
|
||||
IntPtr hProcess,
|
||||
Int64 lpBaseAddress,
|
||||
[In, Out] Byte[] lpBuffer,
|
||||
UInt64 dwSize,
|
||||
out IntPtr lpNumberOfBytesWritten);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
79
SekiroFpsUnlockAndMore/PatternScan.cs
Normal file
79
SekiroFpsUnlockAndMore/PatternScan.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SekiroFpsUnlockAndMore
|
||||
{
|
||||
class PatternScan
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds a pattern or signature inside another process's memory.
|
||||
/// </summary>
|
||||
/// <param name="hProcess">Handle to the process in whose memory pattern will be searched for.</param>
|
||||
/// <param name="pModule">Module which will be searched for the pattern.</param>
|
||||
/// <param name="szPattern">A character-delimited string representing the pattern to be found.</param>
|
||||
/// <param name="szMask">A string of 'x' (match), '!' (not-match), or '?' (wildcard).</param>
|
||||
/// <param name="cDelimiter">Determines how the string will be split. If null, defaults to ' '.</param>
|
||||
/// <returns>The address of the beginning of the pattern if found, 0 if not found</returns>
|
||||
internal static Int64 FindPattern(IntPtr hProcess, ProcessModule pModule, string szPattern, string szMask, char cDelimiter = ' ')
|
||||
{
|
||||
string[] saPattern = szPattern.Split(cDelimiter);
|
||||
byte[] bPattern = new byte[saPattern.Length];
|
||||
for (int i = 0; i < saPattern.Length; i++)
|
||||
bPattern[i] = Convert.ToByte(saPattern[i], 0x10);
|
||||
|
||||
if (bPattern == null || bPattern.Length == 0)
|
||||
throw new ArgumentNullException("Pattern's length is zero!");
|
||||
if (bPattern.Length != szMask.Length)
|
||||
throw new ArgumentException("Pattern's bytes and szMask must be of the same size!");
|
||||
|
||||
long dwStart = 0;
|
||||
if (IntPtr.Size == 4)
|
||||
dwStart = (uint)pModule.BaseAddress;
|
||||
else if (IntPtr.Size == 8)
|
||||
dwStart = (long)pModule.BaseAddress;
|
||||
int nSize = pModule.ModuleMemorySize;
|
||||
|
||||
IntPtr lpNumberOfBytesRead;
|
||||
byte[] bData = new byte[nSize];
|
||||
|
||||
if (!ReadProcessMemory(hProcess, dwStart, bData, nSize, out lpNumberOfBytesRead))
|
||||
throw new Exception("ReadProcessMemory error!");
|
||||
if (lpNumberOfBytesRead.ToInt64() != nSize)
|
||||
throw new Exception("ReadProcessMemory error!");
|
||||
if (bData == null || bData.Length == 0)
|
||||
throw new Exception("Could not read memory in FindPattern.");
|
||||
|
||||
long ix;
|
||||
int iy;
|
||||
bool bFound = false;
|
||||
int patternLength = bPattern.Length;
|
||||
int dataLength = bData.Length - patternLength;
|
||||
|
||||
for (ix = 0; ix < dataLength; ix++)
|
||||
{
|
||||
bFound = true;
|
||||
for (iy = 0; iy < patternLength; iy++)
|
||||
{
|
||||
if ((szMask[iy] == 'x' && bPattern[iy] != bData[ix + iy]) ||
|
||||
(szMask[iy] == '!' && bPattern[iy] == bData[ix + iy]))
|
||||
{
|
||||
bFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bFound)
|
||||
return Convert.ToInt64((long)dwStart + ix);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool ReadProcessMemory(
|
||||
IntPtr hProcess,
|
||||
Int64 lpBaseAddress,
|
||||
[Out] Byte[] lpBuffer,
|
||||
Int64 dwSize,
|
||||
out IntPtr lpNumberOfBytesRead);
|
||||
}
|
||||
}
|
||||
25
SekiroFpsUnlockAndMore/Properties/AssemblyInfo.cs
Normal file
25
SekiroFpsUnlockAndMore/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
[assembly: AssemblyTitle("SekiroFpsUnlockAndMore")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SekiroFpsUnlockAndMore")]
|
||||
[assembly: AssemblyCopyright("Copyright © uberhalit 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None,
|
||||
ResourceDictionaryLocation.SourceAssembly
|
||||
)]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
63
SekiroFpsUnlockAndMore/Properties/Resources.Designer.cs
generated
Normal file
63
SekiroFpsUnlockAndMore/Properties/Resources.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.42000
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SekiroFpsUnlockAndMore.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
/// </summary>
|
||||
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SekiroFpsUnlockAndMore.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
SekiroFpsUnlockAndMore/Properties/Resources.resx
Normal file
117
SekiroFpsUnlockAndMore/Properties/Resources.resx
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
26
SekiroFpsUnlockAndMore/Properties/Settings.Designer.cs
generated
Normal file
26
SekiroFpsUnlockAndMore/Properties/Settings.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.42000
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SekiroFpsUnlockAndMore.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
SekiroFpsUnlockAndMore/Properties/Settings.settings
Normal file
7
SekiroFpsUnlockAndMore/Properties/Settings.settings
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
110
SekiroFpsUnlockAndMore/SekiroFpsUnlockAndMore.csproj
Normal file
110
SekiroFpsUnlockAndMore/SekiroFpsUnlockAndMore.csproj
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{DDB24669-982C-44D6-8375-6176CD97B7E2}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>SekiroFpsUnlockAndMore</RootNamespace>
|
||||
<AssemblyName>SekiroFpsUnlockAndMore</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PatternScan.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="app.manifest" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
17
SekiroFpsUnlockAndMore/app.manifest
Normal file
17
SekiroFpsUnlockAndMore/app.manifest
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
Loading…
Add table
Add a link
Reference in a new issue