Files
Bubberstation/code/modules/wiremod/components/id/access_checker.dm
SkyratBot 5a18ff0bbb [MIRROR] Completely Culls req_access_txt/req_one_access_txt [MDB IGNORE] (#18458)
* Completely Culls req_access_txt/req_one_access_txt (#72281)

Hey there,

Now that every instance of `req_access` and `req_one_access` is a list
of strings, there is absolutely no reason for
req_access_txt/req_access_one_txt to exist. In fact, any instance where
they were still used in the codebase was very convoluted and was very
broken! Don't worry, I fixed it all out, and life is good.

I also dmdoc the surviving access variables, because those were missing.
I went on the side of caution and made a more verbose documentation with
an example just to have people really grasp this (it took me a while to
actually get it)

I believe that we changed _everything_ over to the
req_access/req_one_access system earlier this year in VV, but the
problem is that _new mappers don't understand the difference between the
two systems_. In fact, the "txt" system is completely redundant since
all it does is transition stuff to the "base" system. So, let's just
completely cull the one that's all but deprecated and ensure this
confusion no longer arises. The whole purpose of "txt" seemed to be to
convert the access, but it's all pointless now that we can just read the
list directly.

I'm also 99% certain that the "access check" on vending machines broke
(and didn't seem to have correct logic in the first place? I
legitimately couldn't find a case where it could fail in testing, so I
changed that up), and that's fixed up now. Let me know if I was clueless
there. I know it's short-circuiting now as opposed to "all must be
true", but it just didn't work.

* Completely Culls req_access_txt/req_one_access_txt

* oh the misery

* makes them use the thing that actually works

* test to see if engineering access is breaking it

* Revert "test to see if engineering access is breaking it"

This reverts commit 3cc2c554ff18f435a51601782e64c76193298db7.

* Fix access checks when req_access is null (#72458)

## About The Pull Request
Fixes #72450 - This seems to be an oversight in some of the access
refactors we've been through recently. When there was an assumption in
`check_access_list()` that `req_access` would always be a list, and that
if it was not something terrible had gone wrong and the door should
default to public access.

With the cleanup of the _txt access vars and the introduction of mapping
access helpers, this assumption is no longer true. `req_access` will be
null when multiple helpers are painted onto the same door, so we need to
handle that properly. Thanks to @MrMelbert for spitting out the attached
fix in mapping general and letting me PR it after testing.

This really needs a suite of unit tests around it. San has helpfully
volunteered to work on that for three hours before getting frustrated.

## Why It's Good For The Game
No more public access to engineering lobby, lathe, etc.


## Changelog
🆑 Vire, MrMelbert
fix: The engineering lobby and lathe are no longer public access
fix: Doors will no longer be treated as public access when they have
multiple accesses set on them
/🆑

Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Paxilmaniac <paxilmaniac@gmail.com>
Co-authored-by: Vire <66576896+Maurukas@users.noreply.github.com>
Co-authored-by: Tastyfish <crazychris32@gmail.com>
2023-01-12 11:43:52 -05:00

135 lines
4.8 KiB
Plaintext

/obj/item/circuit_component/compare/access
display_name = "Access Checker"
desc = "Performs a basic comparison between two lists of strings, with additional functions that help in using it to check access on IDs."
category = "ID"
/// A list of the accesses to check
var/datum/port/input/subject_accesses
/// A list of the accesses required to return true
var/datum/port/input/required_accesses
/// Whether to check for all or any of the required accesses
var/datum/port/input/check_any
ui_buttons = list(
"id-card" = "access",
)
/obj/item/circuit_component/compare/access/get_ui_notices()
. = ..()
. += create_ui_notice("When \"Check Any\" is true, returns true if \"Access To Check\" contains ANY value in \"Required Access\".", "orange", "info")
. += create_ui_notice("When \"Check Any\" is false, returns true only if \"Access To Check\" contains ALL values in \"Required Access\".", "orange", "info")
/obj/item/circuit_component/compare/access/populate_custom_ports()
subject_accesses = add_input_port("Access To Check", PORT_TYPE_LIST(PORT_TYPE_STRING))
required_accesses = add_input_port("Required Access", PORT_TYPE_LIST(PORT_TYPE_STRING))
check_any = add_input_port("Check Any", PORT_TYPE_NUMBER)
/obj/item/circuit_component/compare/access/save_data_to_list(list/component_data)
. = ..()
component_data["input_ports_stored_data"] = list(required_accesses.name = list("stored_data" = required_accesses.value))
/obj/item/circuit_component/compare/access/add_to(obj/item/integrated_circuit/added_to)
. = ..()
RegisterSignal(added_to, COMSIG_CIRCUIT_POST_LOAD, PROC_REF(on_post_load))
/obj/item/circuit_component/compare/access/removed_from(obj/item/integrated_circuit/removed_from)
UnregisterSignal(removed_from, COMSIG_CIRCUIT_POST_LOAD)
return ..()
/obj/item/circuit_component/compare/access/proc/on_post_load(datum/source)
regenerate_access()
/obj/item/circuit_component/compare/access/proc/regenerate_access()
var/check_any_value = check_any.value
var/list/required_accesses_list = required_accesses.value
if(!islist(required_accesses_list))
return
if(check_any_value)
LAZYCLEARLIST(req_access)
req_one_access = required_accesses_list.Copy()
else
LAZYCLEARLIST(req_one_access)
req_access = required_accesses_list.Copy()
/obj/item/circuit_component/compare/access/do_comparisons()
return check_access_list(subject_accesses.value)
/obj/item/circuit_component/compare/access/ui_perform_action(mob/user, action)
if(length(required_accesses.connected_ports))
balloon_alert(user, "disconnect port before manually configuring!")
return
interact(user)
/obj/item/circuit_component/compare/access/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "CircuitAccessChecker", display_name)
ui.open()
/obj/item/circuit_component/compare/access/ui_static_data(mob/user)
var/list/data = list()
var/list/regions = list()
var/list/tgui_region_data = SSid_access.all_region_access_tgui
for(var/region in SSid_access.station_regions)
regions += tgui_region_data[region]
if(parent?.admin_only)
regions += tgui_region_data[REGION_CENTCOM]
regions += tgui_region_data[REGION_ALL_GLOBAL]
data["regions"] = regions
return data
/obj/item/circuit_component/compare/access/ui_data(mob/user)
var/list/data = list()
data["accesses"] = required_accesses.value
data["oneAccess"] = check_any.value
return data
/obj/item/circuit_component/compare/access/ui_act(action, params)
. = ..()
if(.)
return
switch(action)
if("clear_all")
required_accesses.set_value(list())
check_any.set_value(0)
. = TRUE
if("grant_all")
required_accesses.set_value(SSid_access.get_region_access_list(list(REGION_ALL_STATION)))
. = TRUE
if("one_access")
check_any.set_value(!check_any.value)
. = TRUE
if("set")
var/list/required_accesses_list = required_accesses.value
var/list/new_accesses_value = LAZYCOPY(required_accesses_list)
var/access = params["access"]
if (!(access in new_accesses_value))
new_accesses_value += access
else
new_accesses_value -= access
required_accesses.set_value(new_accesses_value)
. = TRUE
if("grant_region")
var/list/required_accesses_list = required_accesses.value
var/list/required_accesses_value = LAZYCOPY(required_accesses_list)
var/region = params["region"]
if(isnull(region))
return
required_accesses.set_value(required_accesses_value | SSid_access.get_region_access_list(list(region)))
. = TRUE
if("deny_region")
var/list/required_accesses_list = required_accesses.value
var/list/required_accesses_value = LAZYCOPY(required_accesses_list)
var/region = params["region"]
if(isnull(region))
return
required_accesses.set_value(required_accesses_value - SSid_access.get_region_access_list(list(region)))
. = TRUE
if(.)
regenerate_access()
SStgui.update_uis(parent)