Save fullscreen and read server, password and debug from config.ini
The settings the game saves itself, the quiz settings and now fullscreen, move to settings.cfg (settings_debug.cfg in debug mode). config.ini in the same folder is edited by hand: the server to start with, the API password and debug mode. The game writes it with everything commented out when it is missing and never changes it after that. IniFile reads it: plain key = value lines, whole-line # or ; comments and optional quotes.
This commit is contained in:
1 parent
92e3a66075
commit
d21b3e2ce0
13 files changed
+491
-163
No files matched your search
+125
-44
@@ -8,31 +8,57 @@ const MAX_NUMBER_OF_PLAYERS: int = 7
|
||||
## but apart, e.g. "lttp" for "A Link to the Past". Shorter searches only find names
|
||||
## that contain the text, since a letter or two in order matches most of the library.
|
||||
const LETTERS_FOR_LOOSE_SEARCH: int = 3
|
||||
## The MusicServers that can be picked in the settings.
|
||||
## The MusicServers that can always be picked in the settings.
|
||||
const SERVERS: Array[String] = [
|
||||
"https://music.sanplex.xyz", "https://tmusic.sanplex.xyz", "https://rmusic.sanplex.xyz",
|
||||
"https://old-music.sanplex.xyz", "http://localhost:8080",
|
||||
]
|
||||
## The server debug builds use.
|
||||
## The server debug mode uses.
|
||||
const DEBUG_SERVER: String = "http://localhost:8080"
|
||||
## The winning score debug builds start with, so a game is quick to win while testing.
|
||||
## The winning score debug mode starts with, so a game is quick to win while testing.
|
||||
const DEBUG_WINNING_SCORE: int = 5
|
||||
## The quiz settings that are saved to [method quiz_settings_path] and loaded at start.
|
||||
## The settings the game saves by itself, by section, in [method saved_settings_path].
|
||||
## Count plays in statistics and Prefer less played soundtracks are left out on purpose.
|
||||
const QUIZ_SETTINGS: Array[StringName] = [
|
||||
&"auto_repeat_song", &"stop_after_current", &"hide_next_track", &"hide_beginning",
|
||||
&"hide_for_seconds", &"hide_length", &"hide_ticks", &"winning_score",
|
||||
&"inspiration_list_speed",
|
||||
]
|
||||
## When this environment variable is set, the settings file is kept in that folder instead
|
||||
## of the user's config folder. The tests set it so they never touch the real file.
|
||||
const SAVED_SETTINGS: Dictionary[String, Array] = {
|
||||
"quiz": [
|
||||
&"auto_repeat_song", &"stop_after_current", &"hide_next_track", &"hide_beginning",
|
||||
&"hide_for_seconds", &"hide_length", &"hide_ticks", &"winning_score",
|
||||
&"inspiration_list_speed",
|
||||
],
|
||||
"window": [&"fullscreen"],
|
||||
}
|
||||
## When this environment variable is set, the settings files are kept in that folder
|
||||
## instead of the user's config folder. The tests set it so they never touch the real files.
|
||||
const CONFIG_DIR_ENV: String = "MUSICPLAYER_CONFIG_DIR"
|
||||
const QUIZ_SETTINGS_SECTION: String = "quiz"
|
||||
## The file the user edits by hand. The game writes it only when it is missing, with every
|
||||
## setting commented out.
|
||||
const CONFIG_FILE_NAME: String = "config.ini"
|
||||
const CONFIG_TEMPLATE: String = """# MusicPlayer config. The game never changes this file, so edit it as you like.
|
||||
# Lines starting with # or ; are comments. Remove the # in front of a setting to use it,
|
||||
# and put it back to go back to the default.
|
||||
|
||||
[server]
|
||||
# The MusicServer to use when the game starts. Another one can still be picked in
|
||||
# Settings for as long as the game runs. Debug mode uses http://localhost:8080.
|
||||
#url = https://music.sanplex.xyz
|
||||
|
||||
# Password for getting an API token from the server.
|
||||
#password =
|
||||
|
||||
[game]
|
||||
# true or false. Debug mode uses the local server, starts with a winning score of 5 and
|
||||
# shows DEBUG in the top bar. Without this setting, the game is in debug mode when run
|
||||
# from the Godot editor and not when exported.
|
||||
#debug = true
|
||||
"""
|
||||
|
||||
var default_path: String = "https://music.sanplex.xyz"
|
||||
## Password for getting an API token from the server. Any password works when the
|
||||
## server has none set.
|
||||
var api_password: String = ""
|
||||
## The servers that can be picked in Settings: [constant SERVERS], plus the server from
|
||||
## the config file when it is not one of them.
|
||||
var servers: Array[String] = SERVERS.duplicate()
|
||||
var selected_server: int = 0
|
||||
var is_local: bool = false
|
||||
var is_debug: bool = false
|
||||
@@ -59,53 +85,108 @@ var character_select_open: bool = false
|
||||
var version: String = ProjectSettings.get_setting("application/config/version", "")
|
||||
|
||||
|
||||
# Autoloads are ready before any scene, so debug builds use the local server and the
|
||||
# low winning score from the very first request. The saved quiz settings come after, so
|
||||
# the debug winning score is only used until another one is saved.
|
||||
# Autoloads are ready before any scene, so the server and debug mode from the config file
|
||||
# are used from the very first request. The saved settings come after, so the debug
|
||||
# winning score is only used until another one is saved.
|
||||
func _ready() -> void:
|
||||
if OS.has_feature("debug"):
|
||||
is_debug = true
|
||||
default_path = DEBUG_SERVER
|
||||
selected_server = SERVERS.find(DEBUG_SERVER)
|
||||
apply_config(load_config())
|
||||
load_saved_settings()
|
||||
if fullscreen:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||
|
||||
|
||||
## Uses the server, password and debug mode from the hand-edited [param config]. Settings
|
||||
## left out of it get their defaults.
|
||||
func apply_config(config: IniFile) -> void:
|
||||
is_debug = config.get_bool("game", "debug", OS.has_feature("debug"))
|
||||
default_path = DEBUG_SERVER if is_debug else SERVERS[0]
|
||||
if is_debug:
|
||||
winning_score = DEBUG_WINNING_SCORE
|
||||
load_quiz_settings()
|
||||
var url: String = config.get_string("server", "url")
|
||||
if !url.is_empty():
|
||||
default_path = url.trim_suffix("/")
|
||||
if !servers.has(default_path):
|
||||
servers.append(default_path)
|
||||
selected_server = servers.find(default_path)
|
||||
api_password = config.get_string("server", "password")
|
||||
|
||||
|
||||
## Where the quiz settings are saved: a MusicPlayer folder in the user's config folder,
|
||||
## e.g. [code]~/.config[/code] on Linux and [code]%APPDATA%[/code] on Windows. Debug
|
||||
## builds use a file of their own, so testing never changes the real settings.
|
||||
func quiz_settings_path() -> String:
|
||||
var config_dir: String = OS.get_environment(CONFIG_DIR_ENV)
|
||||
if config_dir.is_empty():
|
||||
config_dir = OS.get_config_dir().path_join("MusicPlayer")
|
||||
var file_name: String = "quiz_settings_debug.cfg" if is_debug else "quiz_settings.cfg"
|
||||
return config_dir.path_join(file_name)
|
||||
## The folder with the settings files: a MusicPlayer folder in the user's config folder,
|
||||
## e.g. [code]~/.config[/code] on Linux and [code]%APPDATA%[/code] on Windows.
|
||||
func config_dir() -> String:
|
||||
var dir: String = OS.get_environment(CONFIG_DIR_ENV)
|
||||
if dir.is_empty():
|
||||
dir = OS.get_config_dir().path_join("MusicPlayer")
|
||||
return dir
|
||||
|
||||
|
||||
## Loads the saved quiz settings. Settings missing from the file, or saved with the
|
||||
## Where the hand-edited config file is.
|
||||
func config_path() -> String:
|
||||
return config_dir().path_join(CONFIG_FILE_NAME)
|
||||
|
||||
|
||||
## Where the game saves its settings. Debug mode uses a file of its own, so testing never
|
||||
## changes the real settings.
|
||||
func saved_settings_path() -> String:
|
||||
var file_name: String = "settings_debug.cfg" if is_debug else "settings.cfg"
|
||||
return config_dir().path_join(file_name)
|
||||
|
||||
|
||||
## Reads the hand-edited config file. When it is missing, writes one with every setting
|
||||
## commented out, so there is a file to edit.
|
||||
func load_config() -> IniFile:
|
||||
var path: String = config_path()
|
||||
if !FileAccess.file_exists(path):
|
||||
DirAccess.make_dir_recursive_absolute(path.get_base_dir())
|
||||
var template: FileAccess = FileAccess.open(path, FileAccess.WRITE)
|
||||
if template != null:
|
||||
template.store_string(CONFIG_TEMPLATE)
|
||||
return IniFile.load_file(path)
|
||||
|
||||
|
||||
## Loads the settings the game saved. Settings missing from the file, or saved with the
|
||||
## wrong type, keep their current value.
|
||||
func load_quiz_settings() -> void:
|
||||
func load_saved_settings() -> void:
|
||||
var file: ConfigFile = ConfigFile.new()
|
||||
if file.load(quiz_settings_path()) != OK:
|
||||
if file.load(saved_settings_path()) != OK:
|
||||
return
|
||||
for setting: StringName in QUIZ_SETTINGS:
|
||||
var current: Variant = get(setting)
|
||||
var saved: Variant = file.get_value(QUIZ_SETTINGS_SECTION, setting, current)
|
||||
if typeof(saved) == typeof(current):
|
||||
set(setting, saved)
|
||||
for section: String in SAVED_SETTINGS:
|
||||
for setting: StringName in SAVED_SETTINGS[section]:
|
||||
set(setting, _saved_value(file, section, setting, get(setting)))
|
||||
|
||||
|
||||
## Saves the quiz settings, so they are the same the next time the game starts.
|
||||
func save_quiz_settings() -> void:
|
||||
var path: String = quiz_settings_path()
|
||||
## Saves the settings in [constant SAVED_SETTINGS], so they are the same the next time
|
||||
## the game starts.
|
||||
func save_settings() -> void:
|
||||
var path: String = saved_settings_path()
|
||||
DirAccess.make_dir_recursive_absolute(path.get_base_dir())
|
||||
var file: ConfigFile = ConfigFile.new()
|
||||
for setting: StringName in QUIZ_SETTINGS:
|
||||
file.set_value(QUIZ_SETTINGS_SECTION, setting, get(setting))
|
||||
for section: String in SAVED_SETTINGS:
|
||||
for setting: StringName in SAVED_SETTINGS[section]:
|
||||
file.set_value(section, setting, get(setting))
|
||||
var error: Error = file.save(path)
|
||||
if error != OK:
|
||||
GameLog.warning("Could not save the quiz settings to %s: %s"
|
||||
% [path, error_string(error)])
|
||||
GameLog.warning("Could not save the settings to %s: %s" % [path, error_string(error)])
|
||||
|
||||
|
||||
## Turns fullscreen on or off and saves it.
|
||||
func set_fullscreen(on: bool) -> void:
|
||||
fullscreen = on
|
||||
if on:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||
else:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
||||
save_settings()
|
||||
|
||||
|
||||
# The saved value of [param key], or [param default] when it is missing or of another type
|
||||
func _saved_value(file: ConfigFile, section: String, key: String, default: Variant) -> Variant:
|
||||
var value: Variant = file.get_value(section, key, default)
|
||||
if typeof(value) != typeof(default):
|
||||
push_warning("%s in [%s] should be a %s, not %s" % [key, section,
|
||||
type_string(typeof(default)), var_to_str(value)])
|
||||
return default
|
||||
return value
|
||||
|
||||
|
||||
func delete_children(node: Node) -> void:
|
||||
|
||||
Reference in new issue
Block a user