aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri/src/core/rules.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src-tauri/src/core/rules.rs')
-rw-r--r--src-tauri/src/core/rules.rs71
1 files changed, 57 insertions, 14 deletions
diff --git a/src-tauri/src/core/rules.rs b/src-tauri/src/core/rules.rs
index 10a40b6..781515a 100644
--- a/src-tauri/src/core/rules.rs
+++ b/src-tauri/src/core/rules.rs
@@ -1,7 +1,8 @@
+use crate::core::config::FeatureFlags;
use crate::core::game_version::Rule;
use std::env;
-pub fn is_library_allowed(rules: &Option<Vec<Rule>>) -> bool {
+pub fn is_library_allowed(rules: &Option<Vec<Rule>>, features: Option<&FeatureFlags>) -> bool {
// If no rules, it's allowed by default
let Some(rules) = rules else {
return true;
@@ -39,19 +40,54 @@ pub fn is_library_allowed(rules: &Option<Vec<Rule>>) -> bool {
let mut allowed = false;
for rule in rules {
- if rule_matches(rule) {
+ if rule_matches(rule, features) {
allowed = rule.action == "allow";
}
}
allowed
}
-fn rule_matches(rule: &Rule) -> bool {
- // Feature-based rules (e.g., is_demo_user, has_quick_plays_support, is_quick_play_singleplayer)
- // are not implemented in this launcher, so we return false for any rule that has features.
- // This prevents adding arguments like --demo, --quickPlayPath, --quickPlaySingleplayer, etc.
- if rule.features.is_some() {
- return false;
+fn rule_matches(rule: &Rule, features: Option<&FeatureFlags>) -> bool {
+ // Feature-based rules: apply only if all listed features evaluate to true
+ if let Some(f) = &rule.features {
+ if let Some(map) = f.as_object() {
+ // If no feature flags provided, we cannot satisfy feature rules
+ let ctx = match features {
+ Some(ff) => ff,
+ None => return false,
+ };
+
+ for (key, val) in map.iter() {
+ let required = val.as_bool().unwrap_or(false);
+ // Map known features
+ let actual = match key.as_str() {
+ "is_demo_user" => ctx.demo_user,
+ "has_quick_plays_support" => ctx.quick_play_enabled,
+ "is_quick_play_singleplayer" => {
+ ctx.quick_play_enabled && ctx.quick_play_singleplayer
+ }
+ "is_quick_play_multiplayer" => {
+ ctx.quick_play_enabled
+ && ctx
+ .quick_play_multiplayer_server
+ .as_ref()
+ .map(|s| !s.is_empty())
+ .unwrap_or(false)
+ }
+ _ => false,
+ };
+ if required && !actual {
+ return false;
+ }
+ if !required && actual {
+ // If rule specifies feature must be false, but it's true, do not match
+ return false;
+ }
+ }
+ } else {
+ // Malformed features object
+ return false;
+ }
}
match &rule.os {
@@ -65,28 +101,35 @@ fn rule_matches(rule: &Rule) -> bool {
"windows" => env::consts::OS == "windows",
_ => false, // Unknown OS name in rule
};
-
+
if !os_match {
return false;
}
}
-
+
// Check architecture if specified
if let Some(arch) = &os_rule.arch {
let current_arch = env::consts::ARCH;
- if arch != current_arch && arch != "x86_64" {
- // "x86" is sometimes used for x86_64, but we only match exact arch
+ // Strict match: only exact architecture or known compatibility mapping
+ let compatible = match (arch.as_str(), current_arch) {
+ ("x86_64", "x86_64") => true,
+ ("x86", "x86") => true,
+ ("aarch64", "aarch64") => true,
+ // Treat "x86" not as matching x86_64 (be strict)
+ _ => arch == current_arch,
+ };
+ if !compatible {
return false;
}
}
-
+
// Check version if specified (for OS version compatibility)
if let Some(_version) = &os_rule.version {
// Version checking would require parsing OS version strings
// For now, we accept all versions (conservative approach)
// In the future, parse version and compare
}
-
+
true
}
}