67 lines
3.0 KiB
GDScript
67 lines
3.0 KiB
GDScript
@tool
|
|
extends RefCounted
|
|
## Monitors the ProjectSettings that shift the user:// base path.
|
|
##
|
|
## Godot derives the user:// directory from THREE settings — config/name,
|
|
## use_custom_user_dir, and custom_user_dir_name (OS::get_user_data_dir reads
|
|
## all three live on every call). Renaming the project, toggling the custom
|
|
## user dir, or changing its name at runtime makes every user:// path silently
|
|
## resolve to a new OS directory. Files written before the shift (sidecar, auth
|
|
## token, audit log, onboarding flags) become orphaned under the old path.
|
|
##
|
|
## This monitor listens to ProjectSettings.settings_changed (available 4.2+),
|
|
## detects a change to any of the three user://-deriving settings, ensures the
|
|
## addon directories exist at the new user:// path, then emits user_path_changed
|
|
## so that all consumers can react knowing the directory structure is already in
|
|
## place. The signal carries no payload: the shift can come from any of the
|
|
## three settings (a custom-dir toggle leaves the name unchanged), so a "user
|
|
## path changed, re-resolve" notification is the only meaningful contract.
|
|
##
|
|
## Usage:
|
|
## var monitor := UserPathMonitor.new()
|
|
## monitor.start()
|
|
## monitor.user_path_changed.connect(_on_user_path_changed)
|
|
|
|
const ProjectPaths := preload("res://addons/godot_mcp_toolkit/paths/project_paths.gd")
|
|
|
|
signal user_path_changed
|
|
|
|
var _cached_name: String = ""
|
|
var _cached_use_custom_dir: bool = false
|
|
var _cached_custom_dir_name: String = ""
|
|
|
|
|
|
## Begin monitoring. Call once after plugin initialization.
|
|
func start() -> void:
|
|
_cache_settings()
|
|
if not ProjectSettings.settings_changed.is_connected(_on_settings_changed):
|
|
ProjectSettings.settings_changed.connect(_on_settings_changed)
|
|
|
|
|
|
## Stop monitoring. Call from _exit_tree() cleanup.
|
|
func stop() -> void:
|
|
if ProjectSettings.settings_changed.is_connected(_on_settings_changed):
|
|
ProjectSettings.settings_changed.disconnect(_on_settings_changed)
|
|
|
|
|
|
func _on_settings_changed() -> void:
|
|
var name := ProjectSettings.get_setting("application/config/name", "")
|
|
var use_custom := bool(ProjectSettings.get_setting("application/config/use_custom_user_dir", false))
|
|
var custom_name := ProjectSettings.get_setting("application/config/custom_user_dir_name", "")
|
|
if name == _cached_name and use_custom == _cached_use_custom_dir and custom_name == _cached_custom_dir_name:
|
|
return
|
|
_cached_name = name
|
|
_cached_use_custom_dir = use_custom
|
|
_cached_custom_dir_name = custom_name
|
|
push_warning("[MCP] user:// path-deriving setting changed - user:// path shifted. Re-creating addon state.")
|
|
# Ensure addon dirs exist at the new user:// path before notifying
|
|
# consumers — they can write immediately without calling ensure_dirs().
|
|
ProjectPaths.ensure_dirs()
|
|
user_path_changed.emit()
|
|
|
|
|
|
func _cache_settings() -> void:
|
|
_cached_name = ProjectSettings.get_setting("application/config/name", "")
|
|
_cached_use_custom_dir = bool(ProjectSettings.get_setting("application/config/use_custom_user_dir", false))
|
|
_cached_custom_dir_name = ProjectSettings.get_setting("application/config/custom_user_dir_name", "")
|