mirror of
https://github.com/Novattz/creamlinux-installer.git
synced 2026-01-24 20:32:51 -05:00
reduce time to detect game bitness
This commit is contained in:
@@ -13,14 +13,19 @@ pub enum Bitness {
|
|||||||
/// Detect the bitness of a Linux Binary by reading ELF header
|
/// Detect the bitness of a Linux Binary by reading ELF header
|
||||||
/// ELF format: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
/// ELF format: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||||
fn detect_binary_bitness(file_path: &Path) -> Option<Bitness> {
|
fn detect_binary_bitness(file_path: &Path) -> Option<Bitness> {
|
||||||
// Read first 5 bytes of the file to check ELF header
|
use std::io::Read;
|
||||||
let bytes = match fs::read(file_path) {
|
|
||||||
Ok(b) if b.len() >= 5 => b,
|
// Only read first 5 bytes
|
||||||
_ => return None,
|
let mut file = fs::File::open(file_path).ok()?;
|
||||||
};
|
let mut bytes = [0u8; 5];
|
||||||
|
|
||||||
|
// Read exactly 5 bytes or fail
|
||||||
|
if file.read_exact(&mut bytes).is_err() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for ELF magic number (0x7F 'E' 'L' 'F')
|
// Check for ELF magic number (0x7F 'E' 'L' 'F')
|
||||||
if bytes.len() < 5 || &bytes[0..4] != b"\x7FELF" {
|
if &bytes[0..4] != b"\x7FELF" {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,14 +65,32 @@ pub fn detect_game_bitness(game_path: &str) -> Result<Bitness, String> {
|
|||||||
"logs",
|
"logs",
|
||||||
"assets",
|
"assets",
|
||||||
"_CommonRedist",
|
"_CommonRedist",
|
||||||
|
"data",
|
||||||
|
"Data",
|
||||||
|
"Docs",
|
||||||
|
"docs",
|
||||||
|
"screenshots",
|
||||||
|
"Screenshots",
|
||||||
|
"saves",
|
||||||
|
"Saves",
|
||||||
|
"mods",
|
||||||
|
"Mods",
|
||||||
|
"maps",
|
||||||
|
"Maps",
|
||||||
];
|
];
|
||||||
|
|
||||||
// Limit scan depth to avoid deep recursion
|
// Limit scan depth to avoid deep recursion
|
||||||
const MAX_DEPTH: usize = 5;
|
const MAX_DEPTH: usize = 3;
|
||||||
|
|
||||||
|
// Stop after finding reasonable confidence (10 binaries)
|
||||||
|
const CONFIDENCE_THRESHOLD: usize = 10;
|
||||||
|
|
||||||
let mut bit64_binaries = Vec::new();
|
let mut bit64_binaries = Vec::new();
|
||||||
let mut bit32_binaries = Vec::new();
|
let mut bit32_binaries = Vec::new();
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
// Scan for Linux binaries
|
// Scan for Linux binaries
|
||||||
for entry in WalkDir::new(game_path_obj)
|
for entry in WalkDir::new(game_path_obj)
|
||||||
.max_depth(MAX_DEPTH)
|
.max_depth(MAX_DEPTH)
|
||||||
@@ -83,6 +106,12 @@ pub fn detect_game_bitness(game_path: &str) -> Result<Bitness, String> {
|
|||||||
})
|
})
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
{
|
{
|
||||||
|
// Early termination when we have high confidence
|
||||||
|
if bit64_binaries.len() >= CONFIDENCE_THRESHOLD || bit32_binaries.len() >= CONFIDENCE_THRESHOLD {
|
||||||
|
debug!("Reached confidence threshold, stopping scan early");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
// Only check files
|
// Only check files
|
||||||
@@ -102,20 +131,24 @@ pub fn detect_game_bitness(game_path: &str) -> Result<Bitness, String> {
|
|||||||
|| filename.starts_with("lib");
|
|| filename.starts_with("lib");
|
||||||
|
|
||||||
// Check if file is executable
|
// Check if file is executable
|
||||||
#[cfg(unix)]
|
let is_executable = {
|
||||||
{
|
{
|
||||||
use std::os::unix::fs::PermissionsExt;
|
// Get metadata once and check both extension and permissions
|
||||||
if let Ok(metadata) = fs::metadata(path) {
|
if let Ok(metadata) = fs::metadata(path) {
|
||||||
let permissions = metadata.permissions();
|
let permissions = metadata.permissions();
|
||||||
let is_executable = permissions.mode() & 0o111 != 0;
|
let executable = permissions.mode() & 0o111 != 0;
|
||||||
|
|
||||||
// Skip files that are neither executable nor have binary extensions
|
// Skip files that are neither executable nor have binary extensions
|
||||||
if !is_executable && !has_binary_extension {
|
executable || has_binary_extension
|
||||||
continue;
|
} else {
|
||||||
|
// If we can't read metadata, only proceed if it has binary extension
|
||||||
|
has_binary_extension
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !is_executable {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect bitness
|
// Detect bitness
|
||||||
@@ -123,8 +156,24 @@ pub fn detect_game_bitness(game_path: &str) -> Result<Bitness, String> {
|
|||||||
debug!("Found {:?} binary: {}", bitness, path.display());
|
debug!("Found {:?} binary: {}", bitness, path.display());
|
||||||
|
|
||||||
match bitness {
|
match bitness {
|
||||||
Bitness::Bit64 => bit64_binaries.push(path.to_path_buf()),
|
Bitness::Bit64 => {
|
||||||
Bitness::Bit32 => bit32_binaries.push(path.to_path_buf()),
|
bit64_binaries.push(path.to_path_buf());
|
||||||
|
|
||||||
|
// If we find libsteam_api.so and it's 64-bit, we can be very confident
|
||||||
|
if filename == "libsteam_api.so" {
|
||||||
|
info!("Found 64-bit libsteam_api.so");
|
||||||
|
return Ok(Bitness::Bit64);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Bitness::Bit32 => {
|
||||||
|
bit32_binaries.push(path.to_path_buf());
|
||||||
|
|
||||||
|
// If we find libsteam_api.so and it's 32-bit, we can be very confident
|
||||||
|
if filename == "libsteam_api.so" {
|
||||||
|
info!("Found 32-bit libsteam_api.so");
|
||||||
|
return Ok(Bitness::Bit32);
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user