Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for multiple splashscreens and AC. #61

Merged
merged 4 commits into from
Oct 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions Classes/Recorders/BaseRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ public IntPtr GetWindowHandleByProcessId(int processId, bool lazy=false) {
try {
if(!lazy) handle = EnumerateProcessWindowHandles(processId).First();
else handle = Process.GetProcessById(processId).MainWindowHandle;

// If the windowHandle we captured is problematic, just return nothing
// Problematic handles are created if the application for example,
// the game displays a splash screen (SplashScreenClass) before launching
// This detection is very primative and only covers specific cases, in the future we should find another way
// to approach this issue. (possibily fetch to see if the window size ratio is not standard?)
var className = GetClassName(handle);
if (className.Replace(" ", "").ToLower().Contains("splashscreen")) throw new Exception($"Window handle is a possible splash screen [{className}]");
}
catch (Exception e) {
Logger.WriteLine($"There was an issue retrieving the window handle for process id [{processId}]: {e.Message}");
Expand Down
2 changes: 1 addition & 1 deletion Classes/Recorders/LibObsRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public override async Task<bool> StartRecording() {

// attempt to retrieve process's window handle to retrieve class name and window title
windowHandle = GetWindowHandleByProcessId(session.Pid, true);
while (windowHandle == IntPtr.Zero && retryAttempt < maxRetryAttempts) {
while ((DetectionService.HasBadWordInClassName(windowHandle) || windowHandle == IntPtr.Zero) && retryAttempt < maxRetryAttempts) {
Logger.WriteLine($"Waiting to retrieve process handle... retry attempt #{retryAttempt}");
await Task.Delay(retryInterval);
retryAttempt++;
Expand Down
37 changes: 30 additions & 7 deletions Classes/Services/DetectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Threading.Tasks;
using RePlays.Utils;
using static RePlays.Utils.Functions;
using static RePlays.Services.RecordingService;

namespace RePlays.Services {
public static class DetectionService {
Expand All @@ -29,6 +30,7 @@ public static class DetectionService {
static readonly string gameDetectionsFile = Path.Join(GetCfgFolder(), "gameDetections.json");
static readonly string nonGameDetectionsFile = Path.Join(GetCfgFolder(), "nonGameDetections.json");
private static Dictionary<string, string> drivePaths = new();
private static List<string> blacklistList = new() { "splashscreen", "launcher", "cheat", "sdl_app" };
public static void Start() {
LoadDetections();

Expand Down Expand Up @@ -227,9 +229,25 @@ public static async void AutoDetectGame(int processId, bool autoRecord = true)
return;
}
}


// If the windowHandle we captured is problematic, just return nothing
// Problematic handles are created if the application for example,
// the game displays a splash screen (SplashScreenClass) before launching
// This detection is very primative and only covers specific cases, in the future we should find another way
// to approach this issue. (possibily fetch to see if the window size ratio is not standard?)
var windowHandle = ActiveRecorder.GetWindowHandleByProcessId(processId, true);
var className = ActiveRecorder.GetClassName(windowHandle);
string gameTitle = GetGameTitle(executablePath);

FileVersionInfo fileInformation = FileVersionInfo.GetVersionInfo(executablePath);
bool hasBadWordInDescription = fileInformation.FileDescription != null ? blacklistList.Where(bannedWord => fileInformation.FileDescription.ToLower().Contains(bannedWord)).Any() : false;
bool hasBadWordInClassName = blacklistList.Where(bannedWord => className.ToLower().Contains(bannedWord)).Any() || blacklistList.Where(bannedWord => className.ToLower().Replace(" ", "").Contains(bannedWord)).Any();
bool hasBadWordInGameTitle = blacklistList.Where(bannedWord => gameTitle.ToLower().Contains(bannedWord)).Any() || blacklistList.Where(bannedWord => gameTitle.ToLower().Replace(" ", "").Contains(bannedWord)).Any();
if (hasBadWordInDescription || hasBadWordInClassName || hasBadWordInGameTitle) return;

if (IsMatchedNonGame(executablePath)) return;
string gameTitle = GetGameTitle(executablePath);

if (!autoRecord)
{
// This is a manual record event so lets just yolo it and assume user knows best
Expand All @@ -241,15 +259,15 @@ public static async void AutoDetectGame(int processId, bool autoRecord = true)

if (!isGame && !executablePath.Contains(@":\Windows"))
{
Logger.WriteLine($"Process [{processId}]:[{Path.GetFileName(executablePath)}] isn't in the game detection list, checking if it might be a game");
Logger.WriteLine($"Process [{processId}][{Path.GetFileName(executablePath)}] isn't in the game detection list, checking if it might be a game");
try
{
var usage = GetGPUUsage(process.Id);
Logger.WriteLine($"PROCESS GPU USAGE [{process.Id}]: {usage}");
if (usage > 10)
{
Logger.WriteLine(
$"This process [{processId}]:[{Path.GetFileName(executablePath)}], appears to be a game.");
$"This process [{processId}][{Path.GetFileName(executablePath)}], appears to be a game.");
isGame = true;
}
}
Expand All @@ -262,20 +280,18 @@ public static async void AutoDetectGame(int processId, bool autoRecord = true)

if (isGame)
{
process.Refresh();

int tries = 0;
while (tries < 40)
{
process.Refresh();
if (process.MainWindowHandle == IntPtr.Zero)
{
Logger.WriteLine($"Process [{processId}]: Got no MainWindow. Retrying... {tries}/20");
Logger.WriteLine($"Process [{processId}][{Path.GetFileName(executablePath)}]: Got no MainWindow. Retrying... {tries}/40");
await Task.Delay(1000);
}
else
{
Logger.WriteLine($"Process [{processId}]: Got MainWindow [{process.MainWindowHandle}]");
Logger.WriteLine($"Process [{processId}][{Path.GetFileName(executablePath)}]: Got MainWindow [{process.MainWindowTitle}]");
break;
}
tries++;
Expand All @@ -294,6 +310,13 @@ public static async void AutoDetectGame(int processId, bool autoRecord = true)
process.Dispose();
}

public static bool HasBadWordInClassName(IntPtr windowHandle)
{
var className = ActiveRecorder.GetClassName(windowHandle);
bool hasBadWordInClassName = blacklistList.Any(bannedWord => className.ToLower().Contains(bannedWord)) || blacklistList.Any(bannedWord => className.ToLower().Replace(" ", "").Contains(bannedWord));
if (hasBadWordInClassName) windowHandle = IntPtr.Zero;
return windowHandle == IntPtr.Zero;
}
public static bool IsMatchedGame(string exeFile) {
exeFile = exeFile.ToLower();
foreach (var game in SettingsService.Settings.detectionSettings.whitelist) {
Expand Down