mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-16 13:12:22 +00:00
Implements a path-based, player-specific whitelisting system (#8725)
* Implements a path-based, player-specific whitelisting system * Readds ported functions * Local testing * Copy-paste error * VV modifications, player panel interface * Testing admin operations * data review
This commit is contained in:
@@ -55,3 +55,7 @@
|
||||
// /atom
|
||||
#define VV_HK_ATOM_EXPLODE "turf_explode"
|
||||
#define VV_HK_ATOM_EMP "turf_emp"
|
||||
|
||||
// /client
|
||||
#define VV_HK_ADD_WHITELIST "add_whitelist"
|
||||
#define VV_HK_DEL_WHITELIST "del_whitelist"
|
||||
|
||||
@@ -58,3 +58,54 @@
|
||||
fileaccess_timer = world.time + FTPDELAY
|
||||
return 0
|
||||
#undef FTPDELAY
|
||||
|
||||
/// Reads path as a text file, splitting it on delimiter matches.
|
||||
/proc/read_lines(path)
|
||||
var/static/regex/pattern = regex(@"\r?\n")
|
||||
return splittext_char(file2text(path) || "", pattern)
|
||||
|
||||
|
||||
/// Read path as a text file to a list, stripping empty space and comments.
|
||||
/proc/read_commentable(path)
|
||||
var/static/regex/pattern = regex(@"^([^#]+)")
|
||||
to_world_log("PATTERN: [pattern] [istype(pattern)]")
|
||||
var/list/result = list()
|
||||
for (var/line in read_lines(path))
|
||||
if (!pattern.Find_char(line))
|
||||
continue
|
||||
line = trim(pattern.group[1])
|
||||
if (!line)
|
||||
continue
|
||||
result += line
|
||||
return result
|
||||
|
||||
|
||||
/// Read path as a text file to a map of key value or key list pairs.
|
||||
/proc/read_config(path, lowercase_keys = TRUE)
|
||||
var/static/regex/pattern = regex(@"\s+")
|
||||
var/list/result = list()
|
||||
for (var/line in read_commentable(path))
|
||||
if (!pattern.Find_char(line))
|
||||
if (lowercase_keys)
|
||||
line = lowertext(line)
|
||||
if (!result[line])
|
||||
result[line] = TRUE
|
||||
else if (result[line] != TRUE)
|
||||
log_error({"Mixed-type key "[line]" discovered in config file "[path]"!"})
|
||||
else
|
||||
log_debug({"Duplicate key "[line]" discovered in config file "[path]"!"})
|
||||
continue
|
||||
var/key = copytext_char(line, 1, pattern.index)
|
||||
if (lowercase_keys)
|
||||
key = lowertext(key)
|
||||
var/value = copytext_char(line, pattern.index + 1)
|
||||
if (!result[key])
|
||||
result[key] = value
|
||||
continue
|
||||
if (!islist(result[key]))
|
||||
if (result[key] == TRUE)
|
||||
log_error({"Mixed-type key "[key]" discovered in config file "[path]"!"})
|
||||
continue
|
||||
result[key] = list(result[key])
|
||||
result[key] += value
|
||||
return result
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
var/global/list/whitelist = list()
|
||||
|
||||
/hook/startup/proc/loadWhitelist()
|
||||
if(config.usewhitelist)
|
||||
load_whitelist()
|
||||
return TRUE
|
||||
|
||||
/proc/load_whitelist()
|
||||
whitelist = file2list("data/whitelist.txt")
|
||||
if(!whitelist.len) whitelist = null
|
||||
|
||||
/proc/check_whitelist(mob/M /*, var/rank*/)
|
||||
if(!whitelist)
|
||||
return FALSE
|
||||
return ("[M.ckey]" in whitelist)
|
||||
|
||||
var/global/list/alien_whitelist = list()
|
||||
|
||||
/hook/startup/proc/loadAlienWhitelist()
|
||||
if(config.usealienwhitelist)
|
||||
load_alienwhitelist()
|
||||
return TRUE
|
||||
|
||||
/proc/load_alienwhitelist()
|
||||
var/text = file2text("config/alienwhitelist.txt")
|
||||
if (!text)
|
||||
log_misc("Failed to load config/alienwhitelist.txt")
|
||||
else
|
||||
alien_whitelist = splittext(text, "\n")
|
||||
|
||||
/proc/is_alien_whitelisted(mob/M, var/datum/species/species)
|
||||
//They are admin or the whitelist isn't in use
|
||||
if(whitelist_overrides(M))
|
||||
return TRUE
|
||||
|
||||
//You did something wrong
|
||||
if(!M || !species)
|
||||
return FALSE
|
||||
|
||||
//The species isn't even whitelisted
|
||||
if(!(species.spawn_flags & SPECIES_IS_WHITELISTED))
|
||||
return TRUE
|
||||
|
||||
//If we have a loaded file, search it
|
||||
if(alien_whitelist)
|
||||
for (var/s in alien_whitelist)
|
||||
if(findtext(s,"[M.ckey] - [species.name]"))
|
||||
return TRUE
|
||||
if(findtext(s,"[M.ckey] - All"))
|
||||
return TRUE
|
||||
|
||||
/proc/is_lang_whitelisted(mob/M, var/datum/language/language)
|
||||
//They are admin or the whitelist isn't in use
|
||||
if(whitelist_overrides(M))
|
||||
return TRUE
|
||||
|
||||
//You did something wrong
|
||||
if(!M || !language)
|
||||
return FALSE
|
||||
|
||||
//The language isn't even whitelisted
|
||||
if(!(language.flags & WHITELISTED))
|
||||
return TRUE
|
||||
|
||||
//If we have a loaded file, search it
|
||||
if(alien_whitelist)
|
||||
for (var/s in alien_whitelist)
|
||||
if(findtext(s,"[M.ckey] - [language.name]"))
|
||||
return TRUE
|
||||
if(findtext(s,"[M.ckey] - All"))
|
||||
return TRUE
|
||||
|
||||
/proc/whitelist_overrides(mob/M)
|
||||
return !config.usealienwhitelist || check_rights(R_ADMIN|R_EVENT, 0, M)
|
||||
|
||||
var/global/list/genemod_whitelist = list()
|
||||
/hook/startup/proc/LoadGenemodWhitelist()
|
||||
global.genemod_whitelist = file2list("config/genemodwhitelist.txt")
|
||||
return TRUE
|
||||
|
||||
/proc/is_genemod_whitelisted(mob/M)
|
||||
return M && M.client && M.client.ckey && LAZYLEN(global.genemod_whitelist) && (M.client.ckey in global.genemod_whitelist)
|
||||
|
||||
/proc/foo()
|
||||
to_world(list2text(global.genemod_whitelist))
|
||||
@@ -97,6 +97,11 @@ var/global/floorIsLava = 0
|
||||
"}
|
||||
|
||||
if (M.client)
|
||||
body += "<br><br><b>Whitelists:</b><br>"
|
||||
body += jointext(M.client.get_whitelists_list(), ", ")
|
||||
body += "<br><A href='?src=\ref[src];modify_whitelist=\ref[M.client];set_value=1'>Add Whitelist</A>"
|
||||
body += " - <A href='?src=\ref[src];modify_whitelist=\ref[M.client];set_value=0'>Remove Whitelist</A>"
|
||||
|
||||
if(!istype(M, /mob/new_player))
|
||||
body += "<br><br>"
|
||||
body += "<b>Transformation:</b>"
|
||||
|
||||
@@ -107,7 +107,9 @@ var/global/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/sendFax,
|
||||
/client/proc/despawn_player,
|
||||
/datum/admins/proc/view_feedback,
|
||||
/client/proc/debug_global_variables
|
||||
/client/proc/debug_global_variables,
|
||||
/client/proc/admin_add_whitelist,
|
||||
/client/proc/admin_del_whitelist
|
||||
)
|
||||
|
||||
var/global/list/admin_verbs_ban = list(
|
||||
@@ -236,7 +238,9 @@ var/global/list/admin_verbs_debug = list(
|
||||
/datum/admins/proc/view_feedback,
|
||||
/client/proc/debug_global_variables,
|
||||
/client/proc/ping_webhook,
|
||||
/client/proc/reload_webhooks
|
||||
/client/proc/reload_webhooks,
|
||||
/client/proc/admin_add_whitelist,
|
||||
/client/proc/admin_del_whitelist
|
||||
)
|
||||
|
||||
var/global/list/admin_verbs_paranoid_debug = list(
|
||||
|
||||
@@ -23,7 +23,7 @@ var/global/jobban_keylist[0] //to store the keys & ranks
|
||||
if (guest_jobbans(rank))
|
||||
if(config.guest_jobban && IsGuestKey(M.key))
|
||||
return "Guest Job-ban"
|
||||
if(config.usewhitelist && !check_whitelist(M))
|
||||
if(config.usewhitelist && !M.client.is_whitelisted(rank)) // This outright doesn't work, but at least compiles. AFAIK we don't use this system at present. ~Ater
|
||||
return "Whitelisted Job"
|
||||
|
||||
return ckey_is_jobbanned(M.ckey, rank)
|
||||
|
||||
@@ -1940,6 +1940,18 @@
|
||||
PlayerNotesFilter()
|
||||
return
|
||||
|
||||
if(href_list["modify_whitelist"])
|
||||
var/client/C = locate(href_list["modify_whitelist"])
|
||||
if(!istype(C))
|
||||
return
|
||||
var/entry = input(usr, "Please enter the path of the whitelist you wish to modify:", "Whitelist target", "") as text|null
|
||||
if(!entry || !ispath(text2path(entry)))
|
||||
return
|
||||
if(href_list["set_value"] == "1")
|
||||
C.add_whitelist(entry)
|
||||
else if(href_list["set_value"] == "0")
|
||||
C.remove_whitelist(entry)
|
||||
|
||||
/mob/living/proc/can_centcom_reply()
|
||||
return 0
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ GLOBAL_DATUM(debug_real_globals, /debug_real_globals) // :3c
|
||||
"admin_log",
|
||||
"admin_ranks",
|
||||
"admin_state",
|
||||
"alien_whitelist",
|
||||
"alldirs",
|
||||
"ahelp_tickets",
|
||||
"adminfaxes",
|
||||
|
||||
@@ -77,7 +77,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
// That last list is entirely arbitrary. Take complaints up with Kholdstare.
|
||||
if((istype(client) && check_rights(R_ADMIN | R_EVENT | R_FUN, 0, client)) || \
|
||||
(LAZYLEN(instance.species_allowed) && species && (species in instance.species_allowed)) || \
|
||||
(config.genemod_whitelist && is_genemod_whitelisted(src) && LAZYLEN(instance.whitelist_allowed) && (species in instance.whitelist_allowed)))
|
||||
(config.genemod_whitelist && client.is_whitelisted(/whitelist/genemod) && LAZYLEN(instance.whitelist_allowed) && (species in instance.whitelist_allowed)))
|
||||
.[instance.name] = instance
|
||||
|
||||
/datum/category_item/player_setup_item/general/body
|
||||
|
||||
125
code/modules/whitelist/admin_ops.dm
Normal file
125
code/modules/whitelist/admin_ops.dm
Normal file
@@ -0,0 +1,125 @@
|
||||
// Rewrites the client's whitelists to disk
|
||||
/proc/write_whitelist(var/key, var/list/whitelist)
|
||||
var/filename = "data/player_saves/[copytext(ckey(key),1,2)]/[ckey(key)]/whitelist.json"
|
||||
log_admin("Writing whitelists to disk for [key] at `[filename]`")
|
||||
try
|
||||
// Byond doesn't have a mechanism for in-place modification of a file, so we have to make a new one and then overwrite the old one.
|
||||
// If this is interrupted, the .tmp file exists and can be loaded at the start of the next round.
|
||||
// The in-game list represents the set of valid entries within the whitelist file, so we may as well remove invalid lines in the process.
|
||||
text2file(json_encode(whitelist), filename + ".tmp")
|
||||
if(fexists(filename) && !fdel(filename))
|
||||
error("Exception when overwriting whitelist file [filename]")
|
||||
if(fcopy(filename + ".tmp", filename))
|
||||
if(!fdel(filename + ".tmp"))
|
||||
error("Exception when deleting tmp whitelist file [filename].tmp")
|
||||
catch(var/exception/E)
|
||||
error("Exception when writing to whitelist file [filename]: [E]")
|
||||
|
||||
|
||||
// Add the selected path to the player's whitelists, if it's valid.
|
||||
/client/proc/add_whitelist(var/path)
|
||||
if(istext(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
return
|
||||
// If they're already whitelisted, do nothing (Also loads the whitelist)
|
||||
if(is_whitelisted(path))
|
||||
return
|
||||
|
||||
log_and_message_admins("[usr ? usr : "SYSTEM"] giving [path] whitelist to [src]", usr)
|
||||
src.whitelists[path] = TRUE
|
||||
write_whitelist(src.ckey, src.whitelists)
|
||||
|
||||
// Remove the selected path from the player's whitelists.
|
||||
/client/proc/remove_whitelist(var/path)
|
||||
if(istext(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
return
|
||||
// If they're not whitelisted, do nothing (Also loads the whitelist)
|
||||
if(!is_whitelisted(path))
|
||||
return
|
||||
|
||||
log_and_message_admins("[usr ? usr : "SYSTEM"] removing [path] whitelist from [src]", usr)
|
||||
src.whitelists -= path
|
||||
write_whitelist(src.ckey, src.whitelists)
|
||||
|
||||
|
||||
/client/proc/admin_add_whitelist()
|
||||
set name = "Whitelist Add Player"
|
||||
set category = "Admin"
|
||||
set desc = "Give a whitelist to a target player"
|
||||
admin_modify_whitelist(TRUE)
|
||||
|
||||
|
||||
/client/proc/admin_del_whitelist()
|
||||
set name = "Whitelist Remove Player"
|
||||
set category = "Admin"
|
||||
set desc = "Remove a whitelist from the target player"
|
||||
admin_modify_whitelist(FALSE)
|
||||
|
||||
|
||||
/client/proc/admin_modify_whitelist(var/set_value)
|
||||
if(!check_rights(R_ADMIN|R_DEBUG))
|
||||
return
|
||||
|
||||
// Get the person to whitelist.
|
||||
var/key = input(src, "Please enter the CKEY of the player whose whitelist you wish to modify:", "Whitelist ckey", "") as text|null
|
||||
if(!key || !length(key))
|
||||
return
|
||||
|
||||
key = ckey(key)
|
||||
if(!fexists("data/player_saves/[copytext(key,1,2)]/[key]/preferences.sav"))
|
||||
to_chat(src, "That player doesn't seem to exist...")
|
||||
return
|
||||
|
||||
// Get the whitelist thing to modify.
|
||||
var/entry = input(src, "Please enter the path of the whitelist you wish to modify:", "Whitelist target", "") as text|null
|
||||
if(!entry || !ispath(text2path(entry)))
|
||||
return
|
||||
|
||||
// If they're logged in, modify it directly.
|
||||
var/client/C = ckey2client(key)
|
||||
if(istype(C))
|
||||
set_value ? C.add_whitelist(entry) : C.remove_whitelist(entry)
|
||||
return
|
||||
|
||||
log_and_message_admins("[src] [set_value ? "giving [entry] whitelist to" : "removing [entry] whitelist from"] [key]", src)
|
||||
|
||||
// Else, we have to find and modify the whitelist file ourselves.
|
||||
var/list/whitelists = load_whitelist(key)
|
||||
|
||||
// They're already whitelisted.
|
||||
if(whitelists[entry] == set_value)
|
||||
return
|
||||
|
||||
whitelists[entry] = set_value
|
||||
write_whitelist(key, whitelists)
|
||||
|
||||
|
||||
/client/vv_get_dropdown()
|
||||
. = ..()
|
||||
VV_DROPDOWN_OPTION(VV_HK_ADD_WHITELIST, "Add whitelist")
|
||||
VV_DROPDOWN_OPTION(VV_HK_DEL_WHITELIST, "Remove whitelist")
|
||||
|
||||
|
||||
/client/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
IF_VV_OPTION(VV_HK_ADD_WHITELIST)
|
||||
if(!check_rights(R_ADMIN|R_DEBUG))
|
||||
return
|
||||
var/entry = input(usr, "Please enter the path of the whitelist you wish to add:", "Whitelist target", "") as text|null
|
||||
if(!entry || !ispath(text2path(entry)))
|
||||
return
|
||||
var/client/C = locate(href_list["target"])
|
||||
if(istype(C))
|
||||
C.add_whitelist(entry)
|
||||
IF_VV_OPTION(VV_HK_DEL_WHITELIST)
|
||||
if(!check_rights(R_ADMIN|R_DEBUG))
|
||||
return
|
||||
var/entry = input(usr, "Please enter the path of the whitelist you wish to remove:", "Whitelist target", "") as text|null
|
||||
if(!entry || !ispath(text2path(entry)))
|
||||
return
|
||||
var/client/C = locate(href_list["target"])
|
||||
if(istype(C))
|
||||
C.remove_whitelist(entry)
|
||||
65
code/modules/whitelist/legacy.dm
Normal file
65
code/modules/whitelist/legacy.dm
Normal file
@@ -0,0 +1,65 @@
|
||||
// Proc to convert the old whitelist systems into the new, shiny, modern system.
|
||||
// This has to do a lot of file I/O because it handles _everyone's_ whitelists, so it's expected to be pretty expensive.
|
||||
// Hence, this has to be manually called by an admin.
|
||||
/proc/load_legacy_whitelist()
|
||||
var/static/list/alienwhitelist_dict = list(
|
||||
"Alai" = /datum/language/tajsign,
|
||||
"Common Skrellian" = /datum/language/skrell,
|
||||
"Diona" = /datum/species/diona,
|
||||
"Promethean" = /datum/species/shapeshifter/promethean,
|
||||
"Schechi" = /datum/language/teshari,
|
||||
"Siik" = /datum/language/tajaran,
|
||||
"Sinta'Unathi" = /datum/language/unathi,
|
||||
"Skrell" = /datum/species/skrell,
|
||||
"Sol Common" = /datum/language/human,
|
||||
"Tajara" = /datum/species/tajaran,
|
||||
"Teshari" = /datum/species/teshari,
|
||||
"Unathi" = /datum/species/unathi,
|
||||
"Zaddat" = /datum/species/zaddat,
|
||||
)
|
||||
|
||||
var/list/whitelists_to_write = list()
|
||||
|
||||
// Load in the alien whitelists
|
||||
for(var/line in read_lines("config/alienwhitelist.txt"))
|
||||
if(!length(line))
|
||||
continue
|
||||
var/static/regex/R = regex(" - ")
|
||||
var/list/tok = splittext(line, R)
|
||||
// Whitelist is no longer valid.
|
||||
if(length(tok) < 2 || !(tok[2] in alienwhitelist_dict))
|
||||
continue
|
||||
|
||||
var/key = ckey(tok[1])
|
||||
// If they don't have a preferences save file, then they probably don't play here any more.
|
||||
if(!fexists("data/player_saves/[copytext(key,1,2)]/[key]/preferences.sav"))
|
||||
continue
|
||||
|
||||
LAZYADDASSOC(whitelists_to_write[key], alienwhitelist_dict[tok[2]], TRUE)
|
||||
|
||||
// Load in the genemod whitelist
|
||||
for(var/line in read_commentable("config/genemodwhitelist.txt"))
|
||||
var/key = ckey(line)
|
||||
// If they don't have a preferences save file, then they probably don't play here any more.
|
||||
if(!fexists("data/player_saves/[copytext(key,1,2)]/[key]/preferences.sav"))
|
||||
continue
|
||||
|
||||
LAZYADDASSOC(whitelists_to_write[key], /whitelist/genemod, TRUE)
|
||||
|
||||
// Write the whitelists to files. Second stage, so we don't make a million individual writes.
|
||||
for(var/key in whitelists_to_write)
|
||||
var/filename = "data/player_saves/[copytext(key,1,2)]/[key]/whitelist.json"
|
||||
var/list/whitelist = whitelists_to_write[key]
|
||||
try
|
||||
// If the file already exists, don't just blindly overwrite it.
|
||||
if(fexists(filename))
|
||||
var/prior_whitelist = file2text(filename) || ""
|
||||
if(length(prior_whitelist))
|
||||
whitelist |= json_decode(prior_whitelist)
|
||||
text2file(json_encode(whitelist), filename + ".tmp")
|
||||
if(fexists(filename) && !fdel(filename))
|
||||
error("Error overwriting whitelist file [filename]")
|
||||
if(!fcopy(filename + ".tmp", filename) || !fdel(filename + ".tmp"))
|
||||
error("Exception when deleting tmp whitelist file [filename].tmp")
|
||||
catch(var/exception/E)
|
||||
error("Exception when writing to whitelist file [filename]: [E]")
|
||||
4
code/modules/whitelist/phony_paths.dm
Normal file
4
code/modules/whitelist/phony_paths.dm
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file is reserved for creating paths that can be used to whitelist
|
||||
// things that aren't directly attributable to specific paths.
|
||||
/whitelist/genemod // This whitelists a collection of sprite_accessories
|
||||
var/name = "Genemods"
|
||||
99
code/modules/whitelist/whitelist.dm
Normal file
99
code/modules/whitelist/whitelist.dm
Normal file
@@ -0,0 +1,99 @@
|
||||
/client/var/list/whitelists = null
|
||||
|
||||
|
||||
// Prints the client's whitelist entries
|
||||
/client/verb/print_whitelist()
|
||||
set name = "Show Whitelist Entries"
|
||||
set desc = "Print the set of things you're whitelisted for."
|
||||
set category = "OOC"
|
||||
|
||||
to_chat(src, "You are whitelisted for:")
|
||||
to_chat(src, jointext(get_whitelists_list(), "\n"))
|
||||
|
||||
/client/proc/get_whitelists_list()
|
||||
. = list()
|
||||
if(src.whitelists == null)
|
||||
src.whitelists = load_whitelist(src.ckey)
|
||||
for(var/key in src.whitelists)
|
||||
try
|
||||
. += initial(initial(key:name))
|
||||
catch()
|
||||
. += key
|
||||
|
||||
|
||||
/proc/load_whitelist(var/key)
|
||||
var/filename = "data/player_saves/[copytext(ckey(key),1,2)]/[ckey(key)]/whitelist.json"
|
||||
try
|
||||
// Check the player-specific whitelist file, if it exists.
|
||||
if(fexists(filename))
|
||||
// Load the whitelist entries from file, or empty string if empty.`
|
||||
. = list()
|
||||
for(var/T in json_decode(file2text(filename) || ""))
|
||||
T = text2path(T)
|
||||
if(!ispath(T))
|
||||
continue
|
||||
.[T] = TRUE
|
||||
|
||||
// Something was removing an entry from the whitelist and interrupted mid-overwrite.
|
||||
else if(fexists(filename + ".tmp") && fcopy(filename + ".tmp", filename))
|
||||
. = load_whitelist(key)
|
||||
if(!fdel(filename + ".tmp"))
|
||||
error("Exception when deleting tmp whitelist file [filename].tmp")
|
||||
|
||||
// Whitelist file doesn't exist, so they aren't whitelisted for anything. Create the file.
|
||||
else if(fexists("data/player_saves/[copytext(ckey(key),1,2)]/[ckey(key)]/preferences.sav"))
|
||||
text2file("", filename)
|
||||
. = list()
|
||||
|
||||
catch(var/exception/E)
|
||||
error("Exception when loading whitelist file [filename]: [E]")
|
||||
|
||||
|
||||
// Returns true if the specified path is in the player's whitelists, false otw.
|
||||
/client/proc/is_whitelisted(var/path)
|
||||
if(istext(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
return
|
||||
// If it hasn't already been loaded, load it.
|
||||
if(src.whitelists == null)
|
||||
src.whitelists = load_whitelist(src.ckey)
|
||||
return src.whitelists[path]
|
||||
|
||||
|
||||
/proc/is_alien_whitelisted(mob/M, var/datum/species/species)
|
||||
//They are admin or the whitelist isn't in use
|
||||
if(whitelist_overrides(M))
|
||||
return TRUE
|
||||
|
||||
//You did something wrong
|
||||
if(!M || !species)
|
||||
return FALSE
|
||||
|
||||
//The species isn't even whitelisted
|
||||
if(!(species.spawn_flags & SPECIES_IS_WHITELISTED))
|
||||
return TRUE
|
||||
|
||||
var/client/C = (!isclient(M)) ? M.client : M
|
||||
return C.is_whitelisted(species.type)
|
||||
|
||||
|
||||
/proc/is_lang_whitelisted(mob/M, var/datum/language/language)
|
||||
//They are admin or the whitelist isn't in use
|
||||
if(whitelist_overrides(M))
|
||||
return TRUE
|
||||
|
||||
//You did something wrong
|
||||
if(!M || !language || !M.client)
|
||||
return FALSE
|
||||
|
||||
//The language isn't even whitelisted
|
||||
if(!(language.flags & WHITELISTED))
|
||||
return TRUE
|
||||
|
||||
var/client/C = (!isclient(M)) ? M.client : M
|
||||
return C.is_whitelisted(language.type)
|
||||
|
||||
|
||||
/proc/whitelist_overrides(mob/M)
|
||||
return !config.usealienwhitelist || check_rights(R_ADMIN|R_EVENT, 0, M)
|
||||
@@ -655,7 +655,6 @@
|
||||
#include "code\game\jobs\access_datum.dm"
|
||||
#include "code\game\jobs\job_controller.dm"
|
||||
#include "code\game\jobs\jobs.dm"
|
||||
#include "code\game\jobs\whitelist.dm"
|
||||
#include "code\game\jobs\job\_alt_title.dm"
|
||||
#include "code\game\jobs\job\assistant.dm"
|
||||
#include "code\game\jobs\job\captain.dm"
|
||||
@@ -3196,6 +3195,10 @@
|
||||
#include "code\modules\webhooks\webhook_roundend.dm"
|
||||
#include "code\modules\webhooks\webhook_roundprep.dm"
|
||||
#include "code\modules\webhooks\webhook_roundstart.dm"
|
||||
#include "code\modules\whitelist\admin_ops.dm"
|
||||
#include "code\modules\whitelist\legacy.dm"
|
||||
#include "code\modules\whitelist\phony_paths.dm"
|
||||
#include "code\modules\whitelist\whitelist.dm"
|
||||
#include "code\modules\xenoarcheaology\anomaly_container.dm"
|
||||
#include "code\modules\xenoarcheaology\boulder.dm"
|
||||
#include "code\modules\xenoarcheaology\effect.dm"
|
||||
|
||||
Reference in New Issue
Block a user