var/list/admin_ranks = list() //list of all admin_rank datums
/datum/admin_rank
var/name = "NoRank"
var/rights = 0
var/list/adds
var/list/subs
/datum/admin_rank/New(init_name, init_rights, list/init_adds, list/init_subs)
name = init_name
switch(name)
if("Removed",null,"")
error("invalid admin-rank name. datum deleted")
del(src)
if(init_rights) rights = init_rights
if(!init_adds) init_adds = list()
if(!init_subs) init_subs = list()
adds = init_adds
subs = init_subs
/datum/admin_rank/proc/process_keyword(word, previous_rights=0)
var/flag = 0
switch(ckey(word))
if("buildmode","build") flag = R_BUILDMODE
if("admin") flag = R_ADMIN
if("ban") flag = R_BAN
if("fun") flag = R_FUN
if("server") flag = R_SERVER
if("debug") flag = R_DEBUG
if("permissions","rights") flag = R_PERMISSIONS
if("possess") flag = R_POSSESS
if("stealth") flag = R_STEALTH
if("rejuv","rejuvinate") flag = R_REJUVINATE
if("varedit") flag = R_VAREDIT
if("everything","host","all") flag = 65535
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
//load our rank - > rights associations
/proc/load_admin_ranks()
admin_ranks.Cut()
if(config.admin_legacy_system)
var/previous_rights = 0
//load text from file and process each line seperately
for(var/line in file2list("config/admin_ranks.txt"))
if(!line) continue
if(findtextEx(line,"#",1,2)) continue
var/next = findtext(line, "=")
var/datum/admin_rank/R = new(ckeyEx(copytext(line, 1, next)))
if(!R) continue
admin_ranks += R
var/prev = findchar(line, "+-", next, 0)
while(prev)
next = findchar(line, "+-", prev+1, 0)
R.process_keyword(copytext(line, prev, next), previous_rights)
prev = next
previous_rights = R.rights
else
establish_db_connection()
if(!dbcon.IsConnected())
world.log << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
diary << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
config.admin_legacy_system = 1
load_admin_ranks()
return
var/DBQuery/query = dbcon.NewQuery("SELECT rank, flags FROM erro_admin_ranks")
query.Execute()
while(query.NextRow())
var/rank_name = ckeyEx(query.item[1])
var/flags = query.item[2]
if(istext(flags)) flags = text2num(flags)
var/datum/admin_rank/R = new(rank_name, flags)
if(!R) continue
admin_ranks += R
#ifdef TESTING
var/msg = "Permission Sets Built:\n"
for(var/datum/admin_rank/R in admin_ranks)
msg += "\t[R.name]"
var/rights = rights2text(R.rights,"\n\t\t",R.adds,R.subs)
if(rights) msg += "\t\t[rights]\n"
testing(msg)
#endif
/proc/load_admins()
//clear the datums references
admin_datums.Cut()
for(var/client/C in admins)
C.remove_admin_verbs()
C.holder = null
admins.Cut()
load_admin_ranks()
var/list/rank_names = list()
for(var/datum/admin_rank/R in admin_ranks)
rank_names[R.name] = R
if(config.admin_legacy_system)
//load text from file
var/list/Lines = file2list("config/admins.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(findtextEx(line,"#",1,2)) continue
//Split the line at every "="
var/list/List = text2list(line, "=")
if(!List.len) continue
//ckey is before the first "="
var/ckey = ckey(List[1])
if(!ckey) continue
//rank follows the first "="
var/rank = ""
if(List.len >= 2)
rank = ckeyEx(List[2])
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D) continue //will occur if an invalid rank is provided
D.associate(directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
else
establish_db_connection()
if(!dbcon.IsConnected())
world.log << "Failed to connect to database in load_admins(). Reverting to legacy system."
diary << "Failed to connect to database in load_admins(). Reverting to legacy system."
config.admin_legacy_system = 1
load_admins()
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank FROM erro_admin")
query.Execute()
while(query.NextRow())
var/ckey = ckey(query.item[1])
var/rank = ckeyEx(query.item[2])
var/datum/admins/D = new(rank, ckey) //create the admin datum and store it for later use
if(!D) continue //will occur if an invalid rank is provided
D.associate(directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in admin_datums)
var/datum/admins/D = admin_datums[ckey]
msg += "\t[ckey] - [D.rank.name]\n"
testing(msg)
#endif
#ifdef TESTING
/client/verb/changerank(newrank in admin_ranks)
if(holder)
holder.rank = newrank
else
holder = new /datum/admins(newrank,ckey)
remove_admin_verbs()
holder.associate(src)
/client/verb/changerights(newrights as num)
if(holder)
holder.rank.rights = newrights
else
holder = new /datum/admins("testing",newrights,ckey)
remove_admin_verbs()
holder.associate(src)
#endif
/datum/admins/proc/edit_rights_topic(list/href_list)
if(!check_rights(R_PERMISSIONS))
message_admins("[key_name_admin(usr)] attempted to edit the admin permissions without sufficient rights.")
log_admin("[key_name(usr)] attempted to edit the admin permissions without sufficient rights.")
return
var/adm_ckey
var/task = href_list["editrights"]
switch(task)
if("add")
var/new_ckey = ckey(input(usr,"New admin's ckey","Admin ckey", null) as text|null)
if(!new_ckey) return
if(new_ckey in admin_datums)
usr << "Error: Topic 'editrights': [new_ckey] is already an admin"
return
adm_ckey = new_ckey
task = "rank"
else
adm_ckey = ckey(href_list["ckey"])
if(!adm_ckey)
usr << "Error: Topic 'editrights': No valid ckey"
return
var/datum/admins/D = admin_datums[adm_ckey]
switch(task)
if("remove")
if(alert("Are you sure you want to remove [adm_ckey]?","Message","Yes","Cancel") == "Yes")
if(!D) return
admin_datums -= adm_ckey
D.disassociate()
message_admins("[key_name_admin(usr)] removed [adm_ckey] from the admins list")
log_admin("[key_name(usr)] removed [adm_ckey] from the admins list")
log_admin_rank_modification(adm_ckey, "Removed")
if("rank")
var/datum/admin_rank/R
var/list/rank_names = list("*New Rank*")
for(R in admin_ranks)
rank_names[R.name] = R
var/new_rank = input("Please select a rank", "New rank", null, null) as null|anything in rank_names
switch(new_rank)
if(null) return
if("*New Rank*")
new_rank = ckeyEx(input("Please input a new rank", "New custom rank", null, null) as null|text)
if(!new_rank) return
R = rank_names[new_rank]
if(!R) //rank with that name doesn't exist yet - make it
if(D) R = new(new_rank, D.rank.rights, D.rank.adds, D.rank.subs) //duplicate our previous admin_rank but with a new name
else R = new(new_rank) //blank new admin_rank
admin_ranks += R
if(D) //they were previously an admin
D.disassociate() //existing admin needs to be disassociated
D.rank = R //set the admin_rank as our rank
else
D = new(R,adm_ckey) //new admin
var/client/C = directory[adm_ckey] //find the client with the specified ckey (if they are logged in)
D.associate(C) //link up with the client and add verbs
message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
log_admin("[key_name(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
log_admin_rank_modification(adm_ckey, new_rank)
if("permissions")
if(!D) return //they're not an admin!
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
D.disassociate()
if(!findtext(D.rank.name, "([adm_ckey])")) //not a modified subrank, need to duplicate the admin_rank datum to prevent modifying others too
D.rank = new("[D.rank.name]([adm_ckey])", D.rank.rights, D.rank.adds, D.rank.subs) //duplicate our previous admin_rank but with a new name
//we don't add this clone to the admin_ranks list, as it is unique to that ckey
D.rank.process_keyword(keyword)
var/client/C = directory[adm_ckey] //find the client with the specified ckey (if they are logged in)
D.associate(C) //link up with the client and add verbs
message_admins("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]")
log_admin("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]")
log_admin_permission_modification(adm_ckey, D.rank.rights)
edit_admin_permissions()