mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 03:27:46 +01:00
/tg/ pref datums (part 1) (#16219)
* TG Prefs (Step 1: JSON savefiles) * TG Prefs (Step 2: Preference Datum Code) * TG Prefs (Step 3: Convert /datum/client_preferences) * TG Prefs (Step 4: Clean up and finishing touches) * Fix some weird compile errors from the rebase
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
if (nref)
|
||||
ref = nref
|
||||
// If a client exists, but they have disabled fancy windowing, disable it!
|
||||
if(user && user.client && !user.client.is_preference_enabled(/datum/client_preference/browser_style))
|
||||
if(!user?.client?.prefs?.read_preference(/datum/preference/toggle/browser_style))
|
||||
return
|
||||
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ var/list/runechat_image_cache = list()
|
||||
owned_by = owner.client
|
||||
RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, PROC_REF(unregister_qdel_self)) // this should only call owned_by if the client is destroyed
|
||||
|
||||
var/extra_length = owned_by.is_preference_enabled(/datum/client_preference/runechat_long_messages)
|
||||
var/extra_length = owned_by.prefs?.read_preference(/datum/preference/toggle/runechat_long_messages)
|
||||
var/maxlen = extra_length ? CHAT_MESSAGE_EXT_LENGTH : CHAT_MESSAGE_LENGTH
|
||||
var/msgwidth = extra_length ? CHAT_MESSAGE_EXT_WIDTH : CHAT_MESSAGE_WIDTH
|
||||
|
||||
@@ -244,10 +244,10 @@ var/list/runechat_image_cache = list()
|
||||
return
|
||||
|
||||
// Doesn't want to hear
|
||||
if(ismob(speaker) && !client.is_preference_enabled(/datum/client_preference/runechat_mob))
|
||||
if(ismob(speaker) && !client.prefs?.read_preference(/datum/preference/toggle/runechat_mob))
|
||||
return
|
||||
// I know the pref is 'obj' but people dunno what turfs are
|
||||
else if(!client.is_preference_enabled(/datum/client_preference/runechat_obj))
|
||||
else if(!client.prefs?.read_preference(/datum/preference/toggle/runechat_obj))
|
||||
return
|
||||
|
||||
// Incapable of receiving
|
||||
@@ -270,7 +270,7 @@ var/list/runechat_image_cache = list()
|
||||
if(italics)
|
||||
extra_classes |= "italics"
|
||||
|
||||
if(client.is_preference_enabled(/datum/client_preference/runechat_border))
|
||||
if(client.prefs?.read_preference(/datum/preference/toggle/runechat_border))
|
||||
extra_classes |= "black_outline"
|
||||
|
||||
var/dist = get_dist(src, speaker)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* A savefile implementation that handles all data using json.
|
||||
* Also saves it using JSON too, fancy.
|
||||
* If you pass in a null path, it simply acts as a memory tree instead, and cannot be saved.
|
||||
*/
|
||||
/datum/json_savefile
|
||||
var/path = ""
|
||||
VAR_PRIVATE/list/tree
|
||||
/// If this is set to true, calling set_entry or remove_entry will automatically call save(), this does not catch modifying a sub-tree, nor do I know how to do that
|
||||
var/auto_save = FALSE
|
||||
/// Cooldown that tracks the time between attempts to download the savefile.
|
||||
COOLDOWN_DECLARE(download_cooldown)
|
||||
|
||||
GENERAL_PROTECT_DATUM(/datum/json_savefile)
|
||||
|
||||
/datum/json_savefile/New(path)
|
||||
src.path = path
|
||||
tree = list()
|
||||
if(path && fexists(path))
|
||||
load()
|
||||
|
||||
/**
|
||||
* Gets an entry from the json tree, with an optional default value.
|
||||
* If no key is specified it throws the entire tree at you instead
|
||||
*/
|
||||
/datum/json_savefile/proc/get_entry(key, default_value)
|
||||
if(!key)
|
||||
return tree
|
||||
return (key in tree) ? tree[key] : default_value
|
||||
|
||||
/// Sets an entry in the tree to the given value
|
||||
/datum/json_savefile/proc/set_entry(key, value)
|
||||
tree[key] = value
|
||||
if(auto_save)
|
||||
save()
|
||||
|
||||
/// Removes the given key from the tree
|
||||
/datum/json_savefile/proc/remove_entry(key)
|
||||
if(key)
|
||||
tree -= key
|
||||
if(auto_save)
|
||||
save()
|
||||
|
||||
/// Wipes the entire tree
|
||||
/datum/json_savefile/proc/wipe()
|
||||
tree?.Cut()
|
||||
|
||||
/datum/json_savefile/proc/load()
|
||||
if(!path || !fexists(path))
|
||||
return FALSE
|
||||
try
|
||||
tree = json_decode(rustg_file_read(path))
|
||||
return TRUE
|
||||
catch(var/exception/err)
|
||||
stack_trace("failed to load json savefile at '[path]': [err]")
|
||||
return FALSE
|
||||
|
||||
/datum/json_savefile/proc/save()
|
||||
if(path)
|
||||
rustg_file_write(json_encode(tree, JSON_PRETTY_PRINT), path)
|
||||
|
||||
/// Traverses the entire dir tree of the given savefile and dynamically assembles the tree from it
|
||||
/datum/json_savefile/proc/import_byond_savefile(savefile/savefile)
|
||||
tree.Cut()
|
||||
var/list/dirs_to_go = list("/" = tree)
|
||||
while(length(dirs_to_go))
|
||||
var/dir = dirs_to_go[1]
|
||||
var/list/region = dirs_to_go[dir]
|
||||
dirs_to_go.Cut(1, 2)
|
||||
savefile.cd = dir
|
||||
for(var/entry in savefile.dir)
|
||||
var/entry_value
|
||||
savefile.cd = "[dir]/[entry]"
|
||||
//eof refers to the path you are cd'ed into, not the savefile as a whole. being false right after cding into an entry means this entry has no buffer, which only happens with nested save file directories
|
||||
if (savefile.eof)
|
||||
region[entry] = list()
|
||||
dirs_to_go["[dir]/[entry]"] = region[entry]
|
||||
continue
|
||||
READ_FILE(savefile, entry_value) //we are cd'ed to the entry, so we don't need to specify a path to read from
|
||||
region[entry] = entry_value
|
||||
|
||||
/// Proc that handles generating a JSON file (prettified if 515 and over!) of a user's preferences and showing it to them.
|
||||
/// Requester is passed in to the ftp() and tgui_alert() procs, and account_name is just used to generate the filename.
|
||||
/// We don't _need_ to pass in account_name since this is reliant on the json_savefile datum already knowing what we correspond to, but it's here to help people keep track of their stuff.
|
||||
/datum/json_savefile/proc/export_json_to_client(mob/requester, account_name)
|
||||
if(!istype(requester) || !path)
|
||||
return
|
||||
|
||||
if(!json_export_checks(requester))
|
||||
return
|
||||
|
||||
// COOLDOWN_START(src, download_cooldown, (CONFIG_GET(number/seconds_cooldown_for_preferences_export) * (1 SECONDS)))
|
||||
COOLDOWN_START(src, download_cooldown, (10 SECONDS))
|
||||
var/file_name = "[account_name ? "[account_name]_" : ""]preferences_[time2text(world.timeofday, "MMM_DD_YYYY_hh-mm-ss")].json"
|
||||
var/temporary_file_storage = "data/preferences_export_working_directory/[file_name]"
|
||||
|
||||
if(!text2file(json_encode(tree, JSON_PRETTY_PRINT), temporary_file_storage))
|
||||
tgui_alert(requester, "Failed to export preferences to JSON! You might need to try again later.", "Export Preferences JSON")
|
||||
return
|
||||
|
||||
var/exportable_json = file(temporary_file_storage)
|
||||
|
||||
DIRECT_OUTPUT(requester, ftp(exportable_json, file_name))
|
||||
fdel(temporary_file_storage)
|
||||
|
||||
/// Proc that just handles all of the checks for exporting a preferences file, returns TRUE if all checks are passed, FALSE otherwise.
|
||||
/// Just done like this to make the code in the export_json_to_client() proc a bit cleaner.
|
||||
/datum/json_savefile/proc/json_export_checks(mob/requester)
|
||||
if(!COOLDOWN_FINISHED(src, download_cooldown))
|
||||
tgui_alert(requester, "You must wait [DisplayTimeText(COOLDOWN_TIMELEFT(src, download_cooldown))] before exporting your preferences again!", "Export Preferences JSON")
|
||||
return FALSE
|
||||
|
||||
if(tgui_alert(requester, "Are you sure you want to export your preferences as a JSON file? This will save to a file on your computer.", "Export Preferences JSON", list("Cancel", "Yes")) == "Yes")
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
@@ -100,7 +100,7 @@
|
||||
if(direct)
|
||||
if(ismob(thing))
|
||||
var/mob/M = thing
|
||||
if(pref_check && !M.is_preference_enabled(pref_check))
|
||||
if(M.check_sound_preference(pref_check))
|
||||
continue
|
||||
SEND_SOUND(thing, S)
|
||||
else
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
mid_length = 60
|
||||
volume = 40
|
||||
extra_range = 10
|
||||
pref_check = /datum/client_preference/supermatter_hum
|
||||
pref_check = /datum/preference/toggle/supermatter_hum
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
mid_length = 70
|
||||
end_sound = 'sound/machines/air_pump/airpumpshutdown.ogg'
|
||||
volume = 15
|
||||
pref_check = /datum/client_preference/air_pump_noise
|
||||
pref_check = /datum/preference/toggle/air_pump_noise
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/looping_sound/weather
|
||||
pref_check = /datum/client_preference/weather_sounds
|
||||
pref_check = /datum/preference/toggle/weather_sounds
|
||||
|
||||
/datum/looping_sound/weather/outside_blizzard
|
||||
mid_sounds = list(
|
||||
@@ -95,4 +95,4 @@
|
||||
volume = 20 //Sound is already quieter in file
|
||||
|
||||
/datum/looping_sound/weather/rain/indoors/heavy
|
||||
volume = 40
|
||||
volume = 40
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
progress = CLAMP(progress, 0, goal)
|
||||
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
|
||||
if(!shown && user.is_preference_enabled(/datum/client_preference/show_progress_bar))
|
||||
if(!shown && user.client?.prefs?.read_preference(/datum/preference/toggle/show_progress_bar))
|
||||
user.client.images += bar
|
||||
shown = 1
|
||||
|
||||
@@ -66,4 +66,4 @@
|
||||
qdel(bar)
|
||||
. = ..()
|
||||
|
||||
#undef PROGRESSBAR_HEIGHT
|
||||
#undef PROGRESSBAR_HEIGHT
|
||||
|
||||
Reference in New Issue
Block a user