package net.minecraft; import com.google.common.collect.Maps; import com.mojang.logging.LogUtils; import java.nio.file.FileStore; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.function.Supplier; import java.util.stream.Collectors; import org.slf4j.Logger; import oshi.SystemInfo; import oshi.hardware.CentralProcessor; import oshi.hardware.GlobalMemory; import oshi.hardware.GraphicsCard; import oshi.hardware.HardwareAbstractionLayer; import oshi.hardware.PhysicalMemory; import oshi.hardware.VirtualMemory; import oshi.hardware.CentralProcessor.ProcessorIdentifier; public class SystemReport { public static final long BYTES_PER_MEBIBYTE = 1048576L; private static final long ONE_GIGA = 1000000000L; private static final Logger LOGGER = LogUtils.getLogger(); private static final String OPERATING_SYSTEM = System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + System.getProperty("os.version"); private static final String JAVA_VERSION = System.getProperty("java.version") + ", " + System.getProperty("java.vendor"); private static final String JAVA_VM_VERSION = System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor"); private final Map entries = Maps.newLinkedHashMap(); public SystemReport() { this.setDetail("Minecraft Version", SharedConstants.getCurrentVersion().getName()); this.setDetail("Minecraft Version ID", SharedConstants.getCurrentVersion().getId()); this.setDetail("Operating System", OPERATING_SYSTEM); this.setDetail("Java Version", JAVA_VERSION); this.setDetail("Java VM Version", JAVA_VM_VERSION); this.setDetail("Memory", (Supplier)(() -> { Runtime runtime = Runtime.getRuntime(); long l = runtime.maxMemory(); long m = runtime.totalMemory(); long n = runtime.freeMemory(); long o = l / 1048576L; long p = m / 1048576L; long q = n / 1048576L; return n + " bytes (" + q + " MiB) / " + m + " bytes (" + p + " MiB) up to " + l + " bytes (" + o + " MiB)"; })); this.setDetail("CPUs", (Supplier)(() -> String.valueOf(Runtime.getRuntime().availableProcessors()))); this.ignoreErrors("hardware", () -> this.putHardware(new SystemInfo())); this.setDetail("JVM Flags", (Supplier)(() -> { List list = (List)Util.getVmArguments().collect(Collectors.toList()); return String.format(Locale.ROOT, "%d total; %s", list.size(), String.join(" ", list)); })); } public void setDetail(String identifier, String value) { this.entries.put(identifier, value); } public void setDetail(String identifier, Supplier valueSupplier) { try { this.setDetail(identifier, (String)valueSupplier.get()); } catch (Exception var4) { LOGGER.warn("Failed to get system info for {}", identifier, var4); this.setDetail(identifier, "ERR"); } } private void putHardware(SystemInfo info) { HardwareAbstractionLayer hardwareAbstractionLayer = info.getHardware(); this.ignoreErrors("processor", () -> this.putProcessor(hardwareAbstractionLayer.getProcessor())); this.ignoreErrors("graphics", () -> this.putGraphics(hardwareAbstractionLayer.getGraphicsCards())); this.ignoreErrors("memory", () -> this.putMemory(hardwareAbstractionLayer.getMemory())); this.ignoreErrors("storage", this::putStorage); } private void ignoreErrors(String groupIdentifier, Runnable executor) { try { executor.run(); } catch (Throwable var4) { LOGGER.warn("Failed retrieving info for group {}", groupIdentifier, var4); } } public static float sizeInMiB(long bytes) { return (float)bytes / 1048576.0F; } private void putPhysicalMemory(List memorySlots) { int i = 0; for (PhysicalMemory physicalMemory : memorySlots) { String string = String.format(Locale.ROOT, "Memory slot #%d ", i++); this.setDetail(string + "capacity (MiB)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", sizeInMiB(physicalMemory.getCapacity())))); this.setDetail(string + "clockSpeed (GHz)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", (float)physicalMemory.getClockSpeed() / 1.0E9F))); this.setDetail(string + "type", physicalMemory::getMemoryType); } } private void putVirtualMemory(VirtualMemory memory) { this.setDetail("Virtual memory max (MiB)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", sizeInMiB(memory.getVirtualMax())))); this.setDetail("Virtual memory used (MiB)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", sizeInMiB(memory.getVirtualInUse())))); this.setDetail("Swap memory total (MiB)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", sizeInMiB(memory.getSwapTotal())))); this.setDetail("Swap memory used (MiB)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", sizeInMiB(memory.getSwapUsed())))); } private void putMemory(GlobalMemory memory) { this.ignoreErrors("physical memory", () -> this.putPhysicalMemory(memory.getPhysicalMemory())); this.ignoreErrors("virtual memory", () -> this.putVirtualMemory(memory.getVirtualMemory())); } private void putGraphics(List gpus) { int i = 0; for (GraphicsCard graphicsCard : gpus) { String string = String.format(Locale.ROOT, "Graphics card #%d ", i++); this.setDetail(string + "name", graphicsCard::getName); this.setDetail(string + "vendor", graphicsCard::getVendor); this.setDetail(string + "VRAM (MiB)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", sizeInMiB(graphicsCard.getVRam())))); this.setDetail(string + "deviceId", graphicsCard::getDeviceId); this.setDetail(string + "versionInfo", graphicsCard::getVersionInfo); } } private void putProcessor(CentralProcessor cpu) { ProcessorIdentifier processorIdentifier = cpu.getProcessorIdentifier(); this.setDetail("Processor Vendor", processorIdentifier::getVendor); this.setDetail("Processor Name", processorIdentifier::getName); this.setDetail("Identifier", processorIdentifier::getIdentifier); this.setDetail("Microarchitecture", processorIdentifier::getMicroarchitecture); this.setDetail("Frequency (GHz)", (Supplier)(() -> String.format(Locale.ROOT, "%.2f", (float)processorIdentifier.getVendorFreq() / 1.0E9F))); this.setDetail("Number of physical packages", (Supplier)(() -> String.valueOf(cpu.getPhysicalPackageCount()))); this.setDetail("Number of physical CPUs", (Supplier)(() -> String.valueOf(cpu.getPhysicalProcessorCount()))); this.setDetail("Number of logical CPUs", (Supplier)(() -> String.valueOf(cpu.getLogicalProcessorCount()))); } private void putStorage() { this.putSpaceForProperty("jna.tmpdir"); this.putSpaceForProperty("org.lwjgl.system.SharedLibraryExtractPath"); this.putSpaceForProperty("io.netty.native.workdir"); this.putSpaceForProperty("java.io.tmpdir"); this.putSpaceForPath("workdir", () -> ""); } private void putSpaceForProperty(String property) { this.putSpaceForPath(property, () -> System.getProperty(property)); } private void putSpaceForPath(String property, Supplier valueSupplier) { String string = "Space in storage for " + property + " (MiB)"; try { String string2 = (String)valueSupplier.get(); if (string2 == null) { this.setDetail(string, ""); return; } FileStore fileStore = Files.getFileStore(Path.of(string2)); this.setDetail( string, String.format(Locale.ROOT, "available: %.2f, total: %.2f", sizeInMiB(fileStore.getUsableSpace()), sizeInMiB(fileStore.getTotalSpace())) ); } catch (InvalidPathException var6) { LOGGER.warn("{} is not a path", property, var6); this.setDetail(string, ""); } catch (Exception var7) { LOGGER.warn("Failed retrieving storage space for {}", property, var7); this.setDetail(string, "ERR"); } } public void appendToCrashReportString(StringBuilder reportAppender) { reportAppender.append("-- ").append("System Details").append(" --\n"); reportAppender.append("Details:"); this.entries.forEach((string, string2) -> { reportAppender.append("\n\t"); reportAppender.append(string); reportAppender.append(": "); reportAppender.append(string2); }); } public String toLineSeparatedString() { return (String)this.entries .entrySet() .stream() .map(entry -> (String)entry.getKey() + ": " + (String)entry.getValue()) .collect(Collectors.joining(System.lineSeparator())); } }