- .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
108 lines
3.8 KiB
C#
108 lines
3.8 KiB
C#
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);
|
|
}
|
|
}
|