mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-25 14:16:30 +01:00
Another take at a new whitelist system (#8887)
* Another take at a new whitelist system * fixes * Fixes usage * Adds python script to reassemble the glorious new whitelist
This commit is contained in:
@@ -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 && !M.client.is_whitelisted(rank)) // This outright doesn't work, but at least compiles. AFAIK we don't use this system at present. ~Ater
|
||||
if(config.usewhitelist && !M.client.is_whitelisted(rank))
|
||||
return "Whitelisted Job"
|
||||
|
||||
return ckey_is_jobbanned(M.ckey, rank)
|
||||
|
||||
@@ -1944,13 +1944,7 @@
|
||||
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)
|
||||
usr.client.admin_modify_whitelist((href_list["set_value"] == "1"), ckey(C.ckey))
|
||||
|
||||
/mob/living/proc/can_centcom_reply()
|
||||
return 0
|
||||
|
||||
@@ -78,7 +78,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 && client.is_whitelisted(/whitelist/genemod) && LAZYLEN(instance.whitelist_allowed) && (species in instance.whitelist_allowed)))
|
||||
(config.genemod_whitelist && client.is_whitelisted("Genemods") && LAZYLEN(instance.whitelist_allowed) && (species in instance.whitelist_allowed)))
|
||||
.[instance.name] = instance
|
||||
|
||||
/datum/category_item/player_setup_item/general/body
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
// Rewrites the whitelists to disk
|
||||
/proc/write_whitelist()
|
||||
var/filename = "config/whitelists.json"
|
||||
log_admin("Writing whitelists to disk 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(global.whitelists), 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/w_key)
|
||||
if(istype(w_key, /datum))
|
||||
var/datum/D = w_key
|
||||
w_key = D:name
|
||||
if(!istext(w_key))
|
||||
return FALSE // Not set.
|
||||
// If they're already whitelisted, do nothing (Also loads the whitelist)
|
||||
if(is_whitelisted(w_key))
|
||||
return
|
||||
|
||||
log_and_message_admins("[usr ? usr : "SYSTEM"] gave [w_key] whitelist to [src]", usr)
|
||||
if(!islist(global.whitelists[ckey(ckey)]))
|
||||
global.whitelists[ckey(ckey)] = list()
|
||||
global.whitelists[ckey(ckey)] += w_key
|
||||
write_whitelist()
|
||||
|
||||
// Remove the selected path from the player's whitelists.
|
||||
/client/proc/remove_whitelist(var/w_key)
|
||||
if(istype(w_key, /datum))
|
||||
var/datum/D = w_key
|
||||
w_key = D:name
|
||||
if(!istext(w_key))
|
||||
return FALSE // Not set.
|
||||
// If they're not whitelisted, do nothing (Also loads the whitelist)
|
||||
if(!is_whitelisted(w_key))
|
||||
return
|
||||
|
||||
log_and_message_admins("[usr ? usr : "SYSTEM"] removed [w_key] whitelist from [src]", usr)
|
||||
global.whitelists[ckey] -= w_key
|
||||
write_whitelist()
|
||||
|
||||
|
||||
/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, var/key = null)
|
||||
if(!check_rights(R_ADMIN|R_DEBUG))
|
||||
return
|
||||
|
||||
// Get the person to whitelist.
|
||||
if(!key)
|
||||
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)
|
||||
|
||||
// Get the whitelist thing to modify.
|
||||
var/entry = input(src, "Please enter the name of the whitelist you wish to modify:", "Whitelist target", "") as null|anything in global.whitelistable
|
||||
if(!entry)
|
||||
return
|
||||
|
||||
if(set_value)
|
||||
if(!islist(global.whitelists[key]))
|
||||
global.whitelists[key] = list()
|
||||
else
|
||||
to_world("is a list: [global.whitelists[ckey(ckey)]]")
|
||||
if(entry in global.whitelists[key])
|
||||
to_chat(src, SPAN_NOTICE("[key] is already whitelisted for [entry]!"))
|
||||
return
|
||||
global.whitelists[key] += entry
|
||||
else
|
||||
if(!islist(global.whitelists[key]))
|
||||
to_chat(src, SPAN_NOTICE("[key] isn't whitelisted for anything!"))
|
||||
return
|
||||
global.whitelists[key] -= entry
|
||||
|
||||
log_and_message_admins("[src] [set_value ? "gave [entry] whitelist to" : "removed [entry] whitelist from"] [key]", src)
|
||||
|
||||
write_whitelist()
|
||||
|
||||
|
||||
/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/client/C = locate(href_list["target"])
|
||||
if(istype(C))
|
||||
usr.client.admin_modify_whitelist(TRUE, ckey(C.ckey))
|
||||
|
||||
IF_VV_OPTION(VV_HK_DEL_WHITELIST)
|
||||
if(!check_rights(R_ADMIN|R_DEBUG))
|
||||
return
|
||||
var/client/C = locate(href_list["target"])
|
||||
if(istype(C))
|
||||
usr.client.admin_modify_whitelist(FALSE, ckey(C.ckey))
|
||||
@@ -1,125 +0,0 @@
|
||||
// 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)
|
||||
@@ -1,65 +0,0 @@
|
||||
// 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]")
|
||||
@@ -1,4 +0,0 @@
|
||||
// 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"
|
||||
@@ -1,4 +1,24 @@
|
||||
/client/var/list/whitelists = null
|
||||
var/list/whitelists = list()
|
||||
var/list/whitelistable = list(
|
||||
SPECIES_DIONA,
|
||||
SPECIES_PROMETHEAN,
|
||||
SPECIES_SKRELL,
|
||||
SPECIES_TAJ,
|
||||
SPECIES_TESHARI,
|
||||
SPECIES_UNATHI,
|
||||
SPECIES_VOX,
|
||||
SPECIES_ZADDAT,
|
||||
LANGUAGE_AKHANI,
|
||||
LANGUAGE_ALAI,
|
||||
LANGUAGE_SCHECHI,
|
||||
LANGUAGE_SIIK,
|
||||
LANGUAGE_SKRELLIAN,
|
||||
LANGUAGE_SKRELLIANFAR,
|
||||
LANGUAGE_SOL_COMMON,
|
||||
LANGUAGE_UNATHI,
|
||||
LANGUAGE_ZADDAT,
|
||||
"Genemods",
|
||||
)
|
||||
|
||||
|
||||
// Prints the client's whitelist entries
|
||||
@@ -10,58 +30,32 @@
|
||||
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
|
||||
return (ckey in global.whitelists) ? global.whitelists[ckey] : list()
|
||||
|
||||
|
||||
/proc/load_whitelist(var/key)
|
||||
var/filename = "data/player_saves/[copytext(ckey(key),1,2)]/[ckey(key)]/whitelist.json"
|
||||
var/filename = "config/whitelists.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()
|
||||
global.whitelists = json_decode(file2text(filename) || "")
|
||||
|
||||
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]
|
||||
/client/proc/is_whitelisted(var/w_key)
|
||||
if(istype(w_key, /datum))
|
||||
var/datum/D = w_key
|
||||
w_key = D:name
|
||||
if(!istext(w_key))
|
||||
return FALSE // Not set.
|
||||
return key in global.whitelists[ckey]
|
||||
|
||||
|
||||
/proc/is_alien_whitelisted(mob/M, var/datum/species/species)
|
||||
/proc/is_alien_whitelisted(mob/M, datum/species/species)
|
||||
//They are admin or the whitelist isn't in use
|
||||
if(whitelist_overrides(M))
|
||||
return TRUE
|
||||
@@ -75,10 +69,10 @@
|
||||
return TRUE
|
||||
|
||||
var/client/C = (!isclient(M)) ? M.client : M
|
||||
return C.is_whitelisted(species.type)
|
||||
return C.is_whitelisted(species.name)
|
||||
|
||||
|
||||
/proc/is_lang_whitelisted(mob/M, var/datum/language/language)
|
||||
/proc/is_lang_whitelisted(mob/M, datum/language/language)
|
||||
//They are admin or the whitelist isn't in use
|
||||
if(whitelist_overrides(M))
|
||||
return TRUE
|
||||
@@ -93,7 +87,7 @@
|
||||
if(!(language.flags & WHITELISTED))
|
||||
return TRUE
|
||||
|
||||
return C.is_whitelisted(language.type)
|
||||
return C.is_whitelisted(language)
|
||||
|
||||
|
||||
/proc/whitelist_overrides(mob/M)
|
||||
|
||||
Reference in New Issue
Block a user