Skip to content

Commit d0a83d3

Browse files
committed
fix unix detection and small tweaks
1 parent 3b36f94 commit d0a83d3

4 files changed

Lines changed: 114 additions & 52 deletions

File tree

src-tauri/src/paths.rs

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1+
use serde::Serialize;
12
use std::{
2-
env::consts::EXE_EXTENSION,
33
fs,
44
path::{Path, PathBuf},
55
};
66

7-
use serde::Serialize;
8-
97
/// Windows EXE suffix for unix systems where EXE_SUFFIX is empty, used for wine support
108
pub const WINDOWS_EXE_EXTENSION: &str = "exe";
119

10+
// This is used to exclude certain file types from being detected as executables. This will match any part of the file extension!
11+
// For example, "file.so.lol" will be excluded because it contains "so"
12+
pub const EXCLUDED_EXE_FILE_EXTENSIONS: [&str; 2] = ["ndll", "so"];
13+
1214
/// Allows engine detectors to find out what type of executable they found, used for wine support
1315
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
1416
pub enum ExecutableType {
@@ -32,6 +34,63 @@ pub fn get_paths_in_folder(folder_path: &Path) -> Vec<PathBuf> {
3234
vec![]
3335
}
3436

37+
fn get_executable_type(path: &Path) -> Option<ExecutableType> {
38+
if path.is_dir() {
39+
return None;
40+
}
41+
42+
#[cfg(target_family = "unix")]
43+
{
44+
// First check if it's an ELF binary (with exclusions)
45+
let valid_elf = loop {
46+
if let Some(ext) = path.extension() {
47+
if let Some(ext_str) = ext.to_str() {
48+
if EXCLUDED_EXE_FILE_EXTENSIONS.contains(&ext_str) {
49+
log::info!(
50+
"Excluded file extension found: {} ({}), skipping ELF check",
51+
ext_str,
52+
path.display()
53+
);
54+
break false;
55+
}
56+
}
57+
}
58+
break true;
59+
};
60+
61+
if valid_elf {
62+
if let Ok(mut file) = fs::File::open(path) {
63+
use std::io::Read;
64+
let mut magic_buf = [0u8; 4];
65+
if file.read_exact(&mut magic_buf).is_ok() && &magic_buf == b"\x7FELF" {
66+
log::info!("ELF executable found: {}", path.display());
67+
return Some(ExecutableType::Platform);
68+
}
69+
}
70+
}
71+
72+
// if not an ELF, check if it has a windows exe suffix for wine support
73+
if let Some(ext) = path.extension() {
74+
if ext == WINDOWS_EXE_EXTENSION {
75+
log::info!("Windows executable found: {}", path.display());
76+
return Some(ExecutableType::WindowsOnUnix);
77+
}
78+
}
79+
}
80+
81+
#[cfg(target_family = "windows")]
82+
{
83+
if let Some(ext) = path.extension() {
84+
if ext == "exe" {
85+
log::info!("Windows executable found: {}", path.display());
86+
return Some(ExecutableType::Platform);
87+
}
88+
}
89+
}
90+
91+
None
92+
}
93+
3594
pub fn get_folders_in_folder(folder_path: &Path) -> Vec<String> {
3695
let folders = get_paths_in_folder(folder_path);
3796
let mut found_folders = vec![];
@@ -53,20 +112,8 @@ pub fn check_for_specific_executable(folder_path: &Path, name: String) -> Option
53112
for file in paths {
54113
if let Some(file_stem) = file.file_stem() {
55114
if !file.is_dir() && *file_stem == *name {
56-
if let Some(ext) = file.extension() {
57-
let is_platform_executable = *ext == *EXE_EXTENSION;
58-
59-
if is_platform_executable {
60-
return Some(ExecutableType::Platform);
61-
} else {
62-
// A check for .exe on unix systems, since some users use Wine to run the engines
63-
#[cfg(target_family = "unix")]
64-
{
65-
if *ext == *WINDOWS_EXE_EXTENSION {
66-
return Some(ExecutableType::WindowsOnUnix);
67-
}
68-
}
69-
}
115+
if let Some(executable_type) = get_executable_type(file.as_path()) {
116+
return Some(executable_type);
70117
}
71118
}
72119
}
@@ -81,22 +128,8 @@ pub fn check_for_any_executable(folder_path: &Path) -> Option<(ExecutableType, P
81128
let mut found_executables: Vec<(ExecutableType, PathBuf)> = vec![];
82129

83130
for file in paths {
84-
if let Some(ext) = file.extension() {
85-
if !file.is_dir() {
86-
let is_platform_executable = *ext == *EXE_EXTENSION;
87-
88-
if is_platform_executable {
89-
found_executables.push((ExecutableType::Platform, file));
90-
} else {
91-
// A check for .exe on unix systems, since some users use Wine to run the engines
92-
#[cfg(target_family = "unix")]
93-
{
94-
if *ext == *WINDOWS_EXE_EXTENSION {
95-
found_executables.push((ExecutableType::WindowsOnUnix, file));
96-
}
97-
}
98-
}
99-
}
131+
if let Some(executable_type) = get_executable_type(file.as_path()) {
132+
found_executables.push((executable_type, file));
100133
}
101134
}
102135

src/components/library/InstanceSettingsPopover.vue

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ defineProps<{
2828

2929
<template>
3030
<PopoverRoot v-model:open="open" :modal="true">
31-
<PopoverTrigger class="simple-button" :disabled="disabled">
31+
<PopoverTrigger
32+
class="btn-simple w-8 rounded-full p-1"
33+
:disabled="disabled"
34+
>
3235
<img src="@assets/images/icon/wrench.png?url" />
3336
</PopoverTrigger>
3437
<PopoverPortal>
@@ -49,7 +52,12 @@ defineProps<{
4952
</fieldset>
5053
<fieldset>
5154
<label for="version"> Version </label>
52-
<input id="version" type="text" v-model="editDraft.version" />
55+
<input
56+
id="version"
57+
type="text"
58+
v-model="editDraft.version"
59+
placeholder="0.0.0"
60+
/>
5361
</fieldset>
5462
<fieldset>
5563
<label for="color"> Color </label>
@@ -66,6 +74,7 @@ defineProps<{
6674
<CollapsibleRoot class="col-span-2" v-model:open="advancedOpen">
6775
<CollapsibleTrigger
6876
class="w-full flex justify-between items-center hover:bg-modfriend-700 text-modfriend-500"
77+
as="legend"
6978
>
7079
Advanced Settings
7180
<img
@@ -97,9 +106,9 @@ defineProps<{
97106
</div>
98107
<PopoverArrow class="fill-modfriend-700" />
99108
<PopoverClose
100-
class="simple-button text-modfriend-50 w-16 absolute right-1 top-1"
109+
class="btn-simple text-modfriend-50 w-6 absolute right-2 top-2.5 rounded-full"
101110
>
102-
<img src="@assets/images/icon/close.png?url" class="size-4" />
111+
<img src="@assets/images/icon/close.png?url" class="size-6" />
103112
</PopoverClose>
104113
</PopoverContent>
105114
</PopoverPortal>
@@ -109,14 +118,6 @@ defineProps<{
109118
<style scoped lang="css">
110119
@reference "maincss";
111120
112-
.simple-button {
113-
@apply size-8 shrink-0 grid place-items-center rounded-full hover:bg-modfriend-500/30 active:bg-modfriend-500/50 transition-colors;
114-
115-
> img {
116-
@apply size-6;
117-
}
118-
}
119-
120121
:deep(.instance-settings) {
121122
@apply bg-modfriend-800 p-2 rounded-xl border border-modfriend-700 flex flex-col gap-4 mb-2 shadow-lg shadow-black/25;
122123
@@ -140,6 +141,9 @@ defineProps<{
140141
textarea {
141142
@apply resize-none;
142143
}
144+
input[type='color'] {
145+
@apply h-full w-full rounded-md;
146+
}
143147
}
144148
}
145149
}

src/main.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@
136136
background-blend-mode: plus-lighter;
137137
}
138138
}
139+
.btn-simple {
140+
@apply shrink-0 flex items-center justify-center hover:bg-modfriend-500/30 active:bg-modfriend-500/50 transition-colors aspect-square;
141+
}
139142
#widget {
140143
/* TODO: stylize this properly */
141144
border: 1px solid black;

src/views/Library.vue

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,14 @@ onMounted(async () => {
356356
357357
if (addedAtLeastOne) {
358358
await refreshEngineContexts();
359+
// Select one of the engines
360+
var newItem: ListDisplayInfo | undefined = listItems.value.find(
361+
(item) =>
362+
item.instance?.folder_path === hoverState.value.paths?.[0],
363+
);
364+
if (newItem) {
365+
selectItem(newItem);
366+
}
359367
}
360368
}
361369
}
@@ -417,6 +425,7 @@ onBeforeUnmount(() => {
417425
<ScrollAreaViewport class="w-full h-full">
418426
<div
419427
class="engine-item"
428+
v-if="listItems.length !== 0"
420429
v-for="item in listItems"
421430
:key="item.canonInfo.folder_path"
422431
:class="{ current: item === curItem }"
@@ -454,6 +463,16 @@ onBeforeUnmount(() => {
454463
</div>
455464
</div>
456465
</div>
466+
<div v-else class="p-4 text-modfriend-500 text-md">
467+
<b>No instances added yet!</b><br />
468+
Add an engine by clicking the
469+
<img
470+
src="@assets/images/icon/add.png?url"
471+
class="inline size-4"
472+
/>
473+
button or by dragging and dropping an engine folder into the
474+
sidebar.
475+
</div>
457476
</ScrollAreaViewport>
458477
</div>
459478
<ScrollAreaScrollbar orientation="vertical" class="scrollbar">
@@ -480,7 +499,7 @@ onBeforeUnmount(() => {
480499
}}
481500
</h1>
482501
<div class="infobar">
483-
<div>
502+
<div class="infobar-content">
484503
<button
485504
class="btn-shiny action-button"
486505
@click="handleLaunchClick"
@@ -519,9 +538,12 @@ onBeforeUnmount(() => {
519538
</span>
520539
</div>
521540
</div>
522-
<div>
523-
<button class="simple-button" @click="handleDelete">
524-
<img src="@assets/images/icon/delete.png?url" class="size-6" />
541+
<div class="flex items-center gap-2">
542+
<button
543+
class="btn-simple w-8 rounded-full p-1"
544+
@click="handleDelete"
545+
>
546+
<img src="@assets/images/icon/delete.png?url" />
525547
</button>
526548
<InstanceSettingsPopover
527549
v-model:open="instanceSettingsOpen"
@@ -551,7 +573,7 @@ onBeforeUnmount(() => {
551573
@reference "maincss";
552574
553575
.content {
554-
@apply flex flex-row min-h-0;
576+
@apply flex flex-row min-h-0 min-w-0 w-full;
555577
}
556578
557579
.list-panel {
@@ -589,7 +611,7 @@ onBeforeUnmount(() => {
589611
}
590612
}
591613
.main-content {
592-
@apply w-full;
614+
@apply flex-1 min-w-0 min-h-0;
593615
594616
/* This is terrible, but it's so that we can have full width components if we need to */
595617
> .scroll-area-content {
@@ -684,7 +706,7 @@ onBeforeUnmount(() => {
684706
}
685707
.infobar {
686708
@apply flex items-center gap-4 mb-4 justify-between;
687-
> div {
709+
> .infobar-content {
688710
@apply flex items-center gap-4;
689711
}
690712

0 commit comments

Comments
 (0)