mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-16 10:11:30 -07:00
132 lines
4.0 KiB
C#
132 lines
4.0 KiB
C#
using Bloxstrap.AppData;
|
|
using Bloxstrap.Integrations;
|
|
using Bloxstrap.Models;
|
|
|
|
namespace Bloxstrap
|
|
{
|
|
public class Watcher : IDisposable
|
|
{
|
|
private readonly InterProcessLock _lock = new("Watcher");
|
|
|
|
private readonly WatcherData? _watcherData;
|
|
|
|
private readonly NotifyIconWrapper? _notifyIcon;
|
|
|
|
public readonly ActivityWatcher? ActivityWatcher;
|
|
|
|
public readonly DiscordRichPresence? RichPresence;
|
|
|
|
public Watcher()
|
|
{
|
|
const string LOG_IDENT = "Watcher";
|
|
|
|
if (!_lock.IsAcquired)
|
|
{
|
|
App.Logger.WriteLine(LOG_IDENT, "Watcher instance already exists");
|
|
return;
|
|
}
|
|
|
|
string? watcherDataArg = App.LaunchSettings.WatcherFlag.Data;
|
|
|
|
if (String.IsNullOrEmpty(watcherDataArg))
|
|
{
|
|
#if DEBUG
|
|
string path = new RobloxPlayerData().ExecutablePath;
|
|
using var gameClientProcess = Process.Start(path);
|
|
|
|
_watcherData = new() { ProcessId = gameClientProcess.Id };
|
|
#else
|
|
throw new Exception("Watcher data not specified");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
_watcherData = JsonSerializer.Deserialize<WatcherData>(Encoding.UTF8.GetString(Convert.FromBase64String(watcherDataArg)));
|
|
}
|
|
|
|
if (_watcherData is null)
|
|
throw new Exception("Watcher data is invalid");
|
|
|
|
if (App.Settings.Prop.EnableActivityTracking)
|
|
{
|
|
ActivityWatcher = new(_watcherData.LogFile);
|
|
|
|
if (App.Settings.Prop.UseDisableAppPatch)
|
|
{
|
|
ActivityWatcher.OnAppClose += delegate
|
|
{
|
|
App.Logger.WriteLine(LOG_IDENT, "Received desktop app exit, closing Roblox");
|
|
using var process = Process.GetProcessById(_watcherData.ProcessId);
|
|
process.CloseMainWindow();
|
|
};
|
|
}
|
|
|
|
if (App.Settings.Prop.UseDiscordRichPresence)
|
|
RichPresence = new(ActivityWatcher);
|
|
}
|
|
|
|
_notifyIcon = new(this);
|
|
}
|
|
|
|
public void KillRobloxProcess() => CloseProcess(_watcherData!.ProcessId, true);
|
|
|
|
public void CloseProcess(int pid, bool force = false)
|
|
{
|
|
const string LOG_IDENT = "Watcher::CloseProcess";
|
|
|
|
try
|
|
{
|
|
using var process = Process.GetProcessById(pid);
|
|
|
|
App.Logger.WriteLine(LOG_IDENT, $"Killing process '{process.ProcessName}' (pid={pid}, force={force})");
|
|
|
|
if (process.HasExited)
|
|
{
|
|
App.Logger.WriteLine(LOG_IDENT, $"PID {pid} has already exited");
|
|
return;
|
|
}
|
|
|
|
if (force)
|
|
process.Kill();
|
|
else
|
|
process.CloseMainWindow();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
App.Logger.WriteLine(LOG_IDENT, $"PID {pid} could not be closed");
|
|
App.Logger.WriteException(LOG_IDENT, ex);
|
|
}
|
|
}
|
|
|
|
public async Task Run()
|
|
{
|
|
if (!_lock.IsAcquired || _watcherData is null)
|
|
return;
|
|
|
|
ActivityWatcher?.Start();
|
|
|
|
while (Utilities.GetProcessesSafe().Any(x => x.Id == _watcherData.ProcessId))
|
|
await Task.Delay(1000);
|
|
|
|
if (_watcherData.AutoclosePids is not null)
|
|
{
|
|
foreach (int pid in _watcherData.AutoclosePids)
|
|
CloseProcess(pid);
|
|
}
|
|
|
|
if (App.LaunchSettings.TestModeFlag.Active)
|
|
Process.Start(Paths.Process, "-settings -testmode");
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
App.Logger.WriteLine("Watcher::Dispose", "Disposing Watcher");
|
|
|
|
_notifyIcon?.Dispose();
|
|
RichPresence?.Dispose();
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
}
|