diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 7fc699f736a..711907c6025 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -18,7 +18,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums adds = init_adds subs = init_subs -/datum/admin_rank/proc/process_keyword(word, previous_rights=0) +/proc/admin_keyword_to_flag(word, previous_rights=0) var/flag = 0 switch(ckey(word)) if("buildmode","build") flag = R_BUILDMODE @@ -36,22 +36,41 @@ var/list/admin_ranks = list() //list of all admin_rank datums if("sound","sounds") flag = R_SOUNDS if("spawn","create") flag = R_SPAWN if("@","prev") flag = previous_rights - else - //isn't a keyword so maybe it's a verbpath? - var/path = text2path(copytext(word,2,findtext(word," ",2,0))) - if(path) - switch(text2ascii(word,1)) - if(43) - if(!subs.Remove(path)) - adds += path //+ - if(45) - if(!adds.Remove(path)) - subs += path //- - return - switch(text2ascii(word,1)) - if(43) rights |= flag //+ - if(45) rights &= ~flag //- - return + return flag + +/proc/admin_keyword_to_path(word) //use this with verb keywords eg +/client/proc/blah + return text2path(copytext(word,2,findtext(word," ",2,0))) + +// Adds/removes rights to this admin_rank +/datum/admin_rank/proc/process_keyword(word, previous_rights=0) + var/flag = admin_keyword_to_flag(word, previous_rights) + if(flag) + switch(text2ascii(word,1)) + if(43) rights |= flag //+ + if(45) rights &= ~flag //- + else + //isn't a keyword so maybe it's a verbpath? + var/path = admin_keyword_to_path(word) + if(path) + switch(text2ascii(word,1)) + if(43) + if(!subs.Remove(path)) + adds += path //+ + if(45) + if(!adds.Remove(path)) + subs += path //- + +// Checks for (keyword-formatted) rights on this admin +/datum/admins/proc/check_keyword(word) + var/flag = admin_keyword_to_flag(word) + if(flag) + return ((rank.rights & flag) == flag) //true only if right has everything in flag + else + var/path = admin_keyword_to_path(word) + for(var/i in owner.verbs) //this needs to be a foreach loop for some reason. in operator and verbs.Find() don't work + if(i == path) + return 1 + return 0 //load our rank - > rights associations /proc/load_admin_ranks() @@ -279,7 +298,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums var/keyword = input("Input permission keyword (one at a time):\ne.g. +BAN or -FUN or +/client/proc/someverb", "Permission toggle", null, null) as null|text if(!keyword) return - if(!check_if_greater_rights_than_holder(D)) + if(!check_keyword(keyword) || !check_if_greater_rights_than_holder(D)) message_admins("[key_name_admin(usr)] attempted to give [adm_ckey] the keyword [keyword] without sufficient rights.") log_admin("[key_name(usr)] attempted to give [adm_ckey] the keyword [keyword] without sufficient rights.") return diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 8b289da6f70..443997a75c5 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -45,6 +45,8 @@ var/list/admin_datums = list() return 1 //they have no rights if(rank.rights == 65535) return 1 //we have all the rights + if(src == other) + return 1 //you always have more rights than yourself if(rank.rights != other.rank.rights) if( (rank.rights & other.rank.rights) == other.rank.rights ) return 1 //we have all the rights they have and more