Skip to content

Commit e786740

Browse files
committed
6-16-25-fix
1 parent c45b1d4 commit e786740

2 files changed

Lines changed: 138 additions & 950 deletions

File tree

config_handler.py

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
import logging
44
import re
5-
from typing import Dict, Optional
5+
from typing import Dict, Any, Optional
66

77

88
import constants
@@ -13,23 +13,6 @@
1313
def modify_config_file(config_path: str, setting: str, new_value: str) -> bool:
1414
"""
1515
Modifies a specific setting in the bluestacks.conf file.
16-
17-
If the setting exists, its value is updated. If it doesn't exist,
18-
it's appended to the end of the file. Handles values enclosed
19-
in double quotes. Ensures the file is only written if changes are made.
20-
21-
Args:
22-
config_path: Absolute path to the bluestacks.conf file.
23-
setting: The configuration key to modify (e.g., "bst.instance.Nougat64.enable_root_access").
24-
new_value: The desired string value for the setting (e.g., "1", "0").
25-
26-
Returns:
27-
True if the file was modified, False otherwise.
28-
29-
Raises:
30-
FileNotFoundError: If config_path does not point to an existing file.
31-
IOError: If there are problems reading or writing the file (caught as Exception).
32-
Exception: For other unexpected file I/O errors.
3316
"""
3417
if not os.path.isfile(config_path):
3518
logger.error(f"Config file not found: {config_path}")
@@ -40,10 +23,8 @@ def modify_config_file(config_path: str, setting: str, new_value: str) -> bool:
4023
)
4124

4225
new_line_content = f'{setting}="{new_value}"'
43-
4426
lines = []
4527
try:
46-
4728
with open(config_path, "r", encoding="utf-8") as file:
4829
lines = file.readlines()
4930
except Exception as e:
@@ -58,19 +39,14 @@ def modify_config_file(config_path: str, setting: str, new_value: str) -> bool:
5839

5940
for line in lines:
6041
stripped_line = line.strip()
61-
6242
if setting_pattern.match(stripped_line):
63-
6443
if stripped_line != new_line_content:
6544
logger.info(
6645
f"Updating setting '{setting}'. Old line: '{stripped_line}', New line: '{new_line_content}'"
6746
)
6847
updated_lines.append(new_line_content + "\n")
6948
changed = True
7049
else:
71-
logger.debug(
72-
f"Setting '{setting}' already has the desired value '{new_value}'. No change needed."
73-
)
7450
updated_lines.append(line)
7551
setting_found_and_updated = True
7652
else:
@@ -80,7 +56,6 @@ def modify_config_file(config_path: str, setting: str, new_value: str) -> bool:
8056
logger.info(
8157
f"Setting '{setting}' not found. Appending with value '{new_value}'."
8258
)
83-
8459
if updated_lines and not updated_lines[-1].endswith("\n"):
8560
updated_lines[-1] += "\n"
8661
updated_lines.append(new_line_content + "\n")
@@ -96,31 +71,30 @@ def modify_config_file(config_path: str, setting: str, new_value: str) -> bool:
9671
raise IOError(
9772
f"Error writing updated configuration file {config_path}: {e}"
9873
) from e
99-
else:
100-
logger.debug(f"No changes were made to {config_path}.")
10174

10275
return changed
10376

10477

105-
def get_all_instance_root_statuses(config_path: str) -> Dict[str, bool]:
78+
def get_complete_root_statuses(config_path: str) -> Dict[str, Any]:
10679
"""
107-
Reads the config file and returns a dictionary of instance names
108-
and their root status (True if enabled, False otherwise).
80+
Reads a config file and returns all instance root statuses AND the global rooting feature status.
10981
11082
Args:
11183
config_path: Path to the bluestacks.conf file.
11284
11385
Returns:
114-
A dictionary mapping instance name (str) to root status (bool).
115-
Returns an empty dictionary if the file is not found or an error occurs during reading.
86+
A dictionary like: {'global_status': bool, 'instance_statuses': {name: bool}}
11687
"""
117-
statuses: Dict[str, bool] = {}
88+
instance_statuses: Dict[str, bool] = {}
89+
global_status: bool = False
90+
11891
if not os.path.isfile(config_path):
11992
logger.warning(
12093
f"Config file not found for reading root statuses: {config_path}"
12194
)
122-
return statuses
95+
return {"global_status": False, "instance_statuses": {}}
12396

97+
# FIX: Regex for both instance-specific and global root keys
12498
instance_pattern = re.compile(
12599
r"^"
126100
+ re.escape(constants.INSTANCE_PREFIX)
@@ -129,24 +103,28 @@ def get_all_instance_root_statuses(config_path: str) -> Dict[str, bool]:
129103
+ r'\s*=\s*"([^"]*)"',
130104
re.IGNORECASE,
131105
)
106+
global_pattern = re.compile(
107+
r"^" + re.escape(constants.FEATURE_ROOTING_KEY) + r'\s*=\s*"1"', re.IGNORECASE
108+
)
132109

133110
try:
134111
with open(config_path, "r", encoding="utf-8") as file:
135112
for line in file:
136-
match = instance_pattern.match(line.strip())
113+
stripped_line = line.strip()
114+
115+
# Check for global key
116+
if global_pattern.match(stripped_line):
117+
global_status = True
118+
logger.debug(f"Found global root status in {config_path}: Enabled")
119+
120+
# Check for instance key
121+
match = instance_pattern.match(stripped_line)
137122
if match:
138-
instance_name = match.group(1)
139-
value = match.group(2)
123+
instance_name, value = match.group(1), match.group(2)
140124
is_enabled = value == "1"
141-
statuses[instance_name] = is_enabled
142-
logger.debug(
143-
f"Found root status for instance '{instance_name}': {'Enabled' if is_enabled else 'Disabled'}"
144-
)
125+
instance_statuses[instance_name] = is_enabled
145126
except Exception:
146127
logger.exception(f"Error reading config file {config_path} for root statuses.")
147-
return {}
148-
149-
if not statuses:
150-
logger.info(f"No instance root status settings found in {config_path}.")
128+
return {"global_status": False, "instance_statuses": {}}
151129

152-
return statuses
130+
return {"global_status": global_status, "instance_statuses": instance_statuses}

0 commit comments

Comments
 (0)