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,107 @@
|
||||
using System.Net.NetworkInformation;
|
||||
using Microsoft.Win32;
|
||||
using SpdUp.Core;
|
||||
|
||||
namespace SpdUp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Network tweaks for gaming: DNS, TCP settings, latency checks.
|
||||
/// All changes are reversible via Restore methods.
|
||||
/// </summary>
|
||||
public sealed class NetworkService
|
||||
{
|
||||
private readonly Dictionary<string, object?> _previousRegValues = new();
|
||||
|
||||
/// <summary>
|
||||
/// Measure round-trip ping to a host.
|
||||
/// </summary>
|
||||
public static async Task<long> PingAsync(string host = "8.8.8.8", int timeoutMs = 2000)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var ping = new Ping();
|
||||
var reply = await ping.SendPingAsync(host, timeoutMs);
|
||||
return reply.Status == IPStatus.Success ? reply.RoundtripTime : -1;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply TCP gaming optimisations via the registry (Nagle, TCP ack frequency, etc.).
|
||||
/// </summary>
|
||||
public void ApplyTcpOptimizations()
|
||||
{
|
||||
try
|
||||
{
|
||||
const string tcpKey = @"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters";
|
||||
using var key = Registry.LocalMachine.OpenSubKey(tcpKey, writable: true);
|
||||
if (key is null) return;
|
||||
|
||||
SetRegistryValueWithBackup(key, tcpKey, "TcpAckFrequency", 1, RegistryValueKind.DWord);
|
||||
SetRegistryValueWithBackup(key, tcpKey, "TCPNoDelay", 1, RegistryValueKind.DWord);
|
||||
SetRegistryValueWithBackup(key, tcpKey, "TcpDelAckTicks", 0, RegistryValueKind.DWord);
|
||||
|
||||
// Also per-interface
|
||||
const string ifacesKey = @"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces";
|
||||
using var ifacesRoot = Registry.LocalMachine.OpenSubKey(ifacesKey);
|
||||
if (ifacesRoot is not null)
|
||||
{
|
||||
foreach (var subKeyName in ifacesRoot.GetSubKeyNames())
|
||||
{
|
||||
using var ifaceKey = ifacesRoot.OpenSubKey(subKeyName, writable: true);
|
||||
if (ifaceKey is null) continue;
|
||||
var fullPath = $"{ifacesKey}\\{subKeyName}";
|
||||
SetRegistryValueWithBackup(ifaceKey, fullPath, "TcpAckFrequency", 1, RegistryValueKind.DWord);
|
||||
SetRegistryValueWithBackup(ifaceKey, fullPath, "TCPNoDelay", 1, RegistryValueKind.DWord);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Info("TCP gaming optimizations applied.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Failed to apply TCP optimizations", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore all TCP settings to their previous values.
|
||||
/// </summary>
|
||||
public void RestoreTcpSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var kvp in _previousRegValues)
|
||||
{
|
||||
var parts = kvp.Key.Split('|');
|
||||
if (parts.Length != 2) continue;
|
||||
|
||||
using var key = Registry.LocalMachine.OpenSubKey(parts[0], writable: true);
|
||||
if (key is null) continue;
|
||||
|
||||
if (kvp.Value is null)
|
||||
key.DeleteValue(parts[1], throwOnMissingValue: false);
|
||||
else
|
||||
key.SetValue(parts[1], kvp.Value);
|
||||
}
|
||||
_previousRegValues.Clear();
|
||||
Logger.Info("TCP settings restored.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Failed to restore TCP settings", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetRegistryValueWithBackup(RegistryKey key, string keyPath, string valueName, object newValue, RegistryValueKind kind)
|
||||
{
|
||||
var backupKey = $"{keyPath}|{valueName}";
|
||||
if (!_previousRegValues.ContainsKey(backupKey))
|
||||
_previousRegValues[backupKey] = key.GetValue(valueName); // null if not present
|
||||
|
||||
key.SetValue(valueName, newValue, kind);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user