Initial commit: SpdUp Windows Gaming Booster v1.0.0
- .NET 8 WPF app with full MVVM architecture - One-click boost: CPU, RAM, GPU, network, services, timer resolution - Real-time system monitor (LibreHardwareMonitor) - Auto game detection (30+ games) - RAM optimizer with kernel-level cleanup - Network optimizer (TCP registry tweaks) - Service manager, process manager, shader cache cleaner - Desktop widget overlay - Debug log viewer - Custom dark gaming theme with trans pride colors - 84 unit tests (xUnit) - Inno Setup installer script - Landing page website
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibreHardwareMonitor.Hardware;
|
||||
using SpdUp.Core;
|
||||
using SpdUp.Models;
|
||||
|
||||
namespace SpdUp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Live system monitoring using performance counters + LibreHardwareMonitor.
|
||||
/// Designed for low overhead – one shared timer drives all consumers.
|
||||
/// </summary>
|
||||
public sealed class MonitoringService : IDisposable
|
||||
{
|
||||
private readonly Timer _timer;
|
||||
private readonly Computer _computer;
|
||||
private readonly PerformanceCounter _cpuCounter;
|
||||
private readonly NetworkService _networkService = new();
|
||||
private readonly string _pingTarget;
|
||||
|
||||
private SystemMetrics _latest = new();
|
||||
private bool _disposed;
|
||||
|
||||
public event Action<SystemMetrics>? MetricsUpdated;
|
||||
|
||||
public SystemMetrics Latest => _latest;
|
||||
|
||||
public MonitoringService(string pingTarget = "8.8.8.8")
|
||||
{
|
||||
_pingTarget = pingTarget;
|
||||
|
||||
// CPU % counter
|
||||
_cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", readOnly: true);
|
||||
_cpuCounter.NextValue(); // prime the counter
|
||||
|
||||
// LibreHardwareMonitor for temps + GPU
|
||||
_computer = new Computer
|
||||
{
|
||||
IsCpuEnabled = true,
|
||||
IsGpuEnabled = true,
|
||||
IsMemoryEnabled = true,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
_computer.Open();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warn($"LibreHardwareMonitor init warning: {ex.Message}");
|
||||
}
|
||||
|
||||
_timer = new Timer(Tick, null, Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
public void Start(int intervalMs = 1000)
|
||||
{
|
||||
_timer.Change(0, intervalMs);
|
||||
Logger.Info($"Monitoring started ({intervalMs} ms interval).");
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
Logger.Info("Monitoring stopped.");
|
||||
}
|
||||
|
||||
public void SetInterval(int intervalMs)
|
||||
{
|
||||
_timer.Change(0, intervalMs);
|
||||
}
|
||||
|
||||
private async void Tick(object? state)
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
try
|
||||
{
|
||||
float cpuUsage = _cpuCounter.NextValue();
|
||||
|
||||
// Memory
|
||||
var mem = new NativeMethods.MEMORYSTATUSEX { dwLength = (uint)Marshal.SizeOf<NativeMethods.MEMORYSTATUSEX>() };
|
||||
NativeMethods.GlobalMemoryStatusEx(ref mem);
|
||||
float ramTotal = mem.ullTotalPhys / 1048576f;
|
||||
float ramUsed = ramTotal - (mem.ullAvailPhys / 1048576f);
|
||||
|
||||
// Hardware sensors
|
||||
float cpuTemp = 0, gpuUsage = 0, gpuTemp = 0;
|
||||
try
|
||||
{
|
||||
foreach (var hw in _computer.Hardware)
|
||||
{
|
||||
hw.Update();
|
||||
foreach (var sensor in hw.Sensors)
|
||||
{
|
||||
if (hw.HardwareType == HardwareType.Cpu &&
|
||||
sensor.SensorType == SensorType.Temperature &&
|
||||
sensor.Name.Contains("Package", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
cpuTemp = sensor.Value ?? 0;
|
||||
}
|
||||
|
||||
if ((hw.HardwareType == HardwareType.GpuNvidia || hw.HardwareType == HardwareType.GpuAmd || hw.HardwareType == HardwareType.GpuIntel))
|
||||
{
|
||||
if (sensor.SensorType == SensorType.Load && sensor.Name.Contains("Core", StringComparison.OrdinalIgnoreCase))
|
||||
gpuUsage = sensor.Value ?? 0;
|
||||
if (sensor.SensorType == SensorType.Temperature && sensor.Name.Contains("Core", StringComparison.OrdinalIgnoreCase))
|
||||
gpuTemp = sensor.Value ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sub in hw.SubHardware)
|
||||
{
|
||||
sub.Update();
|
||||
foreach (var sensor in sub.Sensors)
|
||||
{
|
||||
if (sensor.SensorType == SensorType.Temperature &&
|
||||
sensor.Name.Contains("Package", StringComparison.OrdinalIgnoreCase))
|
||||
cpuTemp = sensor.Value ?? cpuTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { /* sensor read failure – continue with zeros */ }
|
||||
|
||||
// Ping
|
||||
long pingMs = await NetworkService.PingAsync(_pingTarget, 1500);
|
||||
|
||||
_latest = new SystemMetrics
|
||||
{
|
||||
CpuUsage = cpuUsage,
|
||||
RamUsageMB = ramUsed,
|
||||
RamTotalMB = ramTotal,
|
||||
GpuUsage = gpuUsage,
|
||||
CpuTemperature = cpuTemp,
|
||||
GpuTemperature = gpuTemp,
|
||||
NetworkPingMs = pingMs,
|
||||
Fps = 0, // FPS hook not implemented without injection
|
||||
};
|
||||
|
||||
MetricsUpdated?.Invoke(_latest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Monitoring tick error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_disposed = true;
|
||||
_timer.Dispose();
|
||||
_cpuCounter.Dispose();
|
||||
try { _computer.Close(); } catch { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user