using System; using System.IO; using System.Runtime.InteropServices; namespace ModpackLauncher.Services; public static class SystemInfo { private const long DefaultFallbackKB = 8L * 1024 * 1024; // assume 8 GB if detection fails [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetPhysicallyInstalledSystemMemory(out long memoryInKilobytes); /// Total physically installed system RAM in megabytes. public static int TotalPhysicalMemoryMB { get { try { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (GetPhysicallyInstalledSystemMemory(out var kb)) return (int)(kb / 1024); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { // Read MemTotal from /proc/meminfo foreach (var line in File.ReadAllLines("/proc/meminfo")) { if (line.StartsWith("MemTotal:", StringComparison.Ordinal)) { var parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (parts.Length >= 2 && long.TryParse(parts[1], out var memKb)) return (int)(memKb / 1024); } } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { // GC heap-size hint; not perfect but a reasonable fallback for macOS. var gcInfo = GC.GetGCMemoryInfo(); if (gcInfo.TotalAvailableMemoryBytes > 0) return (int)(gcInfo.TotalAvailableMemoryBytes / (1024 * 1024)); } } catch { // Fall through to default } return (int)(DefaultFallbackKB / 1024); } } /// Recommended max user-allocatable RAM (leaves headroom for OS + other apps). public static int SafeMaxAllocationMB { get { var total = TotalPhysicalMemoryMB; // Leave at least 4 GB for OS + browser + Discord + everything else. var headroom = total >= 32 * 1024 ? 6 * 1024 : 4 * 1024; return Math.Max(2048, total - headroom); } } }