diff --git a/code/__DEFINES.dm b/code/__DEFINES.dm index b5f7a43b1c3..dd7905829d5 100644 --- a/code/__DEFINES.dm +++ b/code/__DEFINES.dm @@ -389,11 +389,6 @@ var/list/TAGGERLOCATIONS = list("Disposals", #define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. - -//IMPORTANT! The permissions system supports flags up to 2^30 (possibly 2^31), HOWEVER, once the flag 65536 -//starts being used, an edit to rights2text(rights, seperator="") needs to happen! The edit is prepared -//and commented out. Please uncomment it before assigning that flag. Once you do, delete this note. ~Errorage - //Preference toggles #define SOUND_ADMINHELP 1 #define SOUND_MIDI 2 diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 88c1be1a59d..7b7ba3f78ba 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -368,11 +368,11 @@ var/list/binary = list("0","1") if(!istext(into)) into = "" if(!istext(from)) from = "" var/null_ascii = istext(null_char) ? text2ascii(null_char,1) : null_char - + var/previous = 0 var/start = 1 var/end = length(into) + 1 - + for(var/i=1, i= 65536) - var/rights_pt2 = rights / 65536 - if(rights_pt2 & 1) .+= "[seperator]+NUKESERVER" - if(rights_pt2 & 2) .+= "[seperator]+DDOSALLPLAYERS" - if(rights_pt2 & 4) .+= "[seperator]+SPAWN_RL_SINGULARITY" - */ - +/proc/rights2text(rights, seperator="", list/adds, list/subs) if(rights & R_BUILDMODE) . += "[seperator]+BUILDMODE" if(rights & R_ADMIN) . += "[seperator]+ADMIN" if(rights & R_BAN) . += "[seperator]+BAN" @@ -245,6 +237,11 @@ proc/tg_list2text(list/list, glue=",") if(rights & R_VAREDIT) . += "[seperator]+VAREDIT" if(rights & R_SOUNDS) . += "[seperator]+SOUND" if(rights & R_SPAWN) . += "[seperator]+SPAWN" + + for(var/verbpath in adds) + . += "[seperator]+[verbpath]" + for(var/verbpath in subs) + . += "[seperator]-[verbpath]" return . /proc/ui_style2icon(ui_style) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 0f02fe9cdb3..e8cd48844c5 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -1,57 +1,106 @@ -var/list/admin_ranks = list() //list of all ranks with associated rights +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() - var/previous_rights = 0 + 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 - //load text from file - var/list/Lines = file2list("config/admin_ranks.txt") + var/next = findtext(line, "=") + var/datum/admin_rank/R = new(ckeyEx(copytext(line, 1, next))) + if(!R) continue + admin_ranks += R - //process each line seperately - for(var/line in Lines) - if(!length(line)) continue - if(copytext(line,1,2) == "#") continue + 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/list/List = text2list(line,"+") - if(!List.len) continue - - var/rank = ckeyEx(List[1]) - switch(rank) - if(null,"") continue - if("Removed") continue //Reserved - - var/rights = 0 - for(var/i=2, i<=List.len, i++) - switch(ckey(List[i])) - if("@","prev") rights |= previous_rights - if("buildmode","build") rights |= R_BUILDMODE - if("admin") rights |= R_ADMIN - if("ban") rights |= R_BAN - if("fun") rights |= R_FUN - if("server") rights |= R_SERVER - if("debug") rights |= R_DEBUG - if("permissions","rights") rights |= R_PERMISSIONS - if("possess") rights |= R_POSSESS - if("stealth") rights |= R_STEALTH - if("rejuv","rejuvinate") rights |= R_REJUVINATE - if("varedit") rights |= R_VAREDIT - if("everything","host","all") rights |= ((2 * R_MAXPERMISSION) - 1) - if("sound","sounds") rights |= R_SOUNDS - if("spawn","create") rights |= R_SPAWN - - /* --ONCE FLAGS LARGER OR EQUAL THAN 2^16 = 65536 START BEING USED, USE THIS CODE! - if("nukeeverything") rights += R_NUKEEVERYTHING - */ - - admin_ranks[rank] = rights - previous_rights = rights + 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/rank in admin_ranks) - msg += "\t[rank] - [admin_ranks[rank]]\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 @@ -63,43 +112,39 @@ var/list/admin_ranks = list() //list of all ranks with associated rights 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_admin_ranks() - //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(copytext(line,1,2) == "#") continue + if(findtextEx(line,"#",1,2)) continue - //Split the line at every "-" - var/list/List = text2list(line, "-") + //Split the line at every "=" + var/list/List = text2list(line, "=") if(!List.len) continue - //ckey is before the first "-" + //ckey is before the first "=" var/ckey = ckey(List[1]) if(!ckey) continue - //rank follows the first "-" + //rank follows the first "=" var/rank = "" if(List.len >= 2) rank = ckeyEx(List[2]) - //load permissions associated with this rank - var/rights = admin_ranks[rank] - - //create the admin datum and store it for later use - var/datum/admins/D = new /datum/admins(rank, rights, ckey) - - //find the client for a ckey if they are connected and associate them with the new admin datum - D.associate(directory[ckey]) + 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 - //The current admin system uses SQL - establish_db_connection() if(!dbcon.IsConnected()) world.log << "Failed to connect to database in load_admins(). Reverting to legacy system." @@ -108,33 +153,20 @@ var/list/admin_ranks = list() //list of all ranks with associated rights load_admins() return - var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin") + var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank FROM erro_admin") query.Execute() while(query.NextRow()) - var/ckey = query.item[1] - var/rank = query.item[2] - if(rank == "Removed") continue //This person was de-adminned. They are only in the admin list for archive purposes. - - var/rights = query.item[4] - if(istext(rights)) rights = text2num(rights) - var/datum/admins/D = new /datum/admins(rank, rights, ckey) - - //find the client for a ckey if they are connected and associate them with the new admin datum - D.associate(directory[ckey]) - if(!admin_datums) - world.log << "The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system." - diary << "The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system." - config.admin_legacy_system = 1 - load_admins() - return + 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/rank var/datum/admins/D = admin_datums[ckey] - if(D) rank = D.rank - msg += "\t[ckey] - [rank]\n" + msg += "\t[ckey] - [D.rank.name]\n" testing(msg) #endif @@ -143,18 +175,110 @@ var/list/admin_ranks = list() //list of all ranks with associated rights /client/verb/changerank(newrank in admin_ranks) if(holder) holder.rank = newrank - holder.rights = admin_ranks[newrank] else - holder = new /datum/admins(newrank,admin_ranks[newrank],ckey) + holder = new /datum/admins(newrank,ckey) remove_admin_verbs() holder.associate(src) /client/verb/changerights(newrights as num) if(holder) - holder.rights = newrights + 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() \ No newline at end of file diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c8848ddba8b..354f2cd9720 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -198,19 +198,25 @@ var/list/admin_verbs_hideable = list( /client/proc/add_admin_verbs() if(holder) + var/rights = holder.rank.rights verbs += admin_verbs_default - if(holder.rights & R_BUILDMODE) verbs += /client/proc/togglebuildmodeself - if(holder.rights & R_ADMIN) verbs += admin_verbs_admin - if(holder.rights & R_BAN) verbs += admin_verbs_ban - if(holder.rights & R_FUN) verbs += admin_verbs_fun - if(holder.rights & R_SERVER) verbs += admin_verbs_server - if(holder.rights & R_DEBUG) verbs += admin_verbs_debug - if(holder.rights & R_POSSESS) verbs += admin_verbs_possess - if(holder.rights & R_PERMISSIONS) verbs += admin_verbs_permissions - if(holder.rights & R_STEALTH) verbs += /client/proc/stealth - if(holder.rights & R_REJUVINATE) verbs += admin_verbs_rejuv - if(holder.rights & R_SOUNDS) verbs += admin_verbs_sounds - if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn + if(rights & R_BUILDMODE) verbs += /client/proc/togglebuildmodeself + if(rights & R_ADMIN) verbs += admin_verbs_admin + if(rights & R_BAN) verbs += admin_verbs_ban + if(rights & R_FUN) verbs += admin_verbs_fun + if(rights & R_SERVER) verbs += admin_verbs_server + if(rights & R_DEBUG) verbs += admin_verbs_debug + if(rights & R_POSSESS) verbs += admin_verbs_possess + if(rights & R_PERMISSIONS) verbs += admin_verbs_permissions + if(rights & R_STEALTH) verbs += /client/proc/stealth + if(rights & R_REJUVINATE) verbs += admin_verbs_rejuv + if(rights & R_SOUNDS) verbs += admin_verbs_sounds + if(rights & R_SPAWN) verbs += admin_verbs_spawn + + for(var/path in holder.rank.adds) + verbs += path + for(var/path in holder.rank.subs) + verbs -= path /client/proc/remove_admin_verbs() verbs.Remove( @@ -246,6 +252,8 @@ var/list/admin_verbs_hideable = list( /client/proc/kaboom, /client/proc/cmd_admin_areatest ) + if(holder) + verbs.Remove(holder.rank.adds) /client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs set name = "Adminverbs - Hide Most" diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 00c77eb7d78..cd84af74980 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -1,9 +1,9 @@ var/list/admin_datums = list() /datum/admins - var/rank = "Temporary Admin" + var/datum/admin_rank/rank + var/client/owner = null - var/rights = 0 var/fakekey = null var/datum/marked_datum @@ -13,14 +13,17 @@ var/list/admin_datums = list() var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel var/admincaster_signature //What you'll sign the newsfeeds as -/datum/admins/New(initial_rank = "Temporary Admin", initial_rights = 0, ckey) +/datum/admins/New(datum/admin_rank/R, ckey) if(!ckey) error("Admin datum created without a ckey argument. Datum has been deleted") del(src) return + if(!istype(R)) + error("Admin datum created without a rank. Datum has been deleted") + del(src) + return + rank = R admincaster_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]" - rank = initial_rank - rights = initial_rights admin_datums[ckey] = src /datum/admins/proc/associate(client/C) @@ -65,14 +68,10 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. if(usr.client.holder) if(!other || !other.holder) return 1 - - var/usr_rights_pt2 = usr.client.holder.rights / 65536 - var/other_rights_pt2 = other.holder.rights / 65536 - if( (usr_rights_pt2 & other_rights_pt2) == other_rights_pt2 ) //Check values larger than 65535 - if(usr.client.holder.rights != other.holder.rights) //Check values smaller than 65536 - if( (usr.client.holder.rights & other.holder.rights) == other.holder.rights ) - return 1 //we have all the rights they have and more - usr << "Error: Cannot proceed. They have more or equal rights to us." + if(usr.client.holder.rank.rights != other.holder.rank.rights) //Check values smaller than 65536 + if( (usr.client.holder.rank.rights & other.holder.rank.rights) == other.holder.rank.rights ) + return 1 //we have all the rights they have and more + usr << "Error: Cannot proceed. They have greater or equal rights to us." return 0 @@ -85,17 +84,8 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. //This proc checks whether subject has at least ONE of the rights specified in rights_required. /proc/check_rights_for(client/subject, rights_required) - if(subject) - if(rights_required) - if(subject.holder) - if(rights_required >= 65536) - var/rights_required_pt2 = rights_required / 65536 - var/rights_pt2 = subject.holder.rights / 65536 - if(rights_required_pt2 & rights_pt2) - return 1 - if(rights_required & subject.holder.rights) - return 1 - else - if(subject.holder) - return 1 + if(subject && subject.holder && subject.holder.rank) + if(rights_required && !(rights_required & subject.holder.rank.rights)) + return 0 + return 1 return 0 \ No newline at end of file diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index 26d1c8b88cf..174dba2ddd7 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -19,21 +19,24 @@
- + + + "} for(var/adm_ckey in admin_datums) var/datum/admins/D = admin_datums[adm_ckey] if(!D) continue - var/rank = D.rank ? D.rank : "*none*" - var/rights = rights2text(D.rights," ") + + var/rights = rights2text(D.rank.rights," ") if(!rights) rights = "*none*" - + output += "" output += "" - output += "" - output += "" + output += "" + output += "" + output += "" output += "" output += {" @@ -42,7 +45,7 @@ "} - usr << browse(output,"window=editrights;size=600x500") + usr << browse(output,"window=editrights;size=900x650") /datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank) if(config.admin_legacy_system) return @@ -93,55 +96,30 @@ log_query.Execute() usr << "\blue Admin rank changed." + /datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission) if(config.admin_legacy_system) return - - if(!usr.client) - return - - if (check_rights(R_PERMISSIONS)) - return + if(!usr.client) return + if(check_rights(R_PERMISSIONS)) return establish_db_connection() if(!dbcon.IsConnected()) usr << "\red Failed to establish database connection" return - if(!adm_ckey || !new_permission) - return - - adm_ckey = ckey(adm_ckey) - - if(!adm_ckey) - return - - if(istext(new_permission)) - new_permission = text2num(new_permission) - - if(!istext(adm_ckey) || !isnum(new_permission)) + if(!adm_ckey || !istext(adm_ckey) || !isnum(new_permission)) return var/DBQuery/select_query = dbcon.NewQuery("SELECT id, flags FROM erro_admin WHERE ckey = '[adm_ckey]'") select_query.Execute() var/admin_id - var/admin_rights while(select_query.NextRow()) admin_id = text2num(select_query.item[1]) - admin_rights = text2num(select_query.item[2]) - if(!admin_id) - return + if(!admin_id) return - if(admin_rights & new_permission) //This admin already has this permission, so we are removing it. - var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]") - insert_query.Execute() - var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');") - log_query.Execute() - usr << "\blue Permission removed." - else //This admin doesn't have this permission, so we are adding it. - var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]") - insert_query.Execute() - var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')") - log_query.Execute() - usr << "\blue Permission added." \ No newline at end of file + var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = [new_permission] WHERE id = [admin_id]") + insert_query.Execute() + var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edit permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');") + log_query.Execute() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index d0e4d15b2ba..2b68a0f4583 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -146,98 +146,7 @@ DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid ) else if(href_list["editrights"]) - 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"] - if(task == "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 if(task != "show") - 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] - - if(task == "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") - - else if(task == "rank") - var/new_rank - if(admin_ranks.len) - new_rank = input("Please select a rank", "New rank", null, null) as null|anything in (admin_ranks|"*New Rank*") - else - new_rank = input("Please select a rank", "New rank", null, null) as null|anything in list("Game Master","Game Admin", "Trial Admin", "Admin Observer","*New Rank*") - - var/rights = 0 - if(D) - rights = D.rights - switch(new_rank) - if(null,"") return - if("*New Rank*") - new_rank = input("Please input a new rank", "New custom rank", null, null) as null|text - if(config.admin_legacy_system) - new_rank = ckeyEx(new_rank) - if(!new_rank) - usr << "Error: Topic 'editrights': Invalid rank" - return - if(config.admin_legacy_system) - if(admin_ranks.len) - if(new_rank in admin_ranks) - rights = admin_ranks[new_rank] //we typed a rank which already exists, use its rights - else - admin_ranks[new_rank] = 0 //add the new rank to admin_ranks - else - if(config.admin_legacy_system) - new_rank = ckeyEx(new_rank) - rights = admin_ranks[new_rank] //we input an existing rank, use its rights - - if(D) - D.disassociate() //remove adminverbs and unlink from client - D.rank = new_rank //update the rank - D.rights = rights //update the rights based on admin_ranks (default: 0) - else - D = new /datum/admins(new_rank, rights, adm_ckey) - - 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) - - else if(task == "permissions") - if(!D) return - var/list/permissionlist = list() - for(var/i=1, i<=R_MAXPERMISSION, i<<=1) //that <<= is shorthand for i = i << 1. Which is a left bitshift - permissionlist[rights2text(i)] = i - var/new_permission = input("Select a permission to turn on/off", "Permission toggle", null, null) as null|anything in permissionlist - if(!new_permission) return - D.rights ^= permissionlist[new_permission] - - message_admins("[key_name_admin(usr)] toggled the [new_permission] permission of [adm_ckey]") - log_admin("[key_name(usr)] toggled the [new_permission] permission of [adm_ckey]") - log_admin_permission_modification(adm_ckey, permissionlist[new_permission]) - - edit_admin_permissions() + edit_rights_topic(href_list) else if(href_list["call_shuttle"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 54d2f35038a..2dc35b85ce4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -210,7 +210,7 @@ datum/preferences dat += "Adminhelp Sound: " dat += "[(toggles & SOUND_ADMINHELP)?"On":"Off"]
" - if(unlock_content || check_rights_for(user, R_ADMIN)) + if(unlock_content || check_rights_for(user.client, R_ADMIN)) dat += "OOC:   Change
" if(unlock_content) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 25db03a46ab..e7db4dce795 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -380,7 +380,7 @@ var/list/slot_equipment_priority = list( \ set category = "OOC" var/is_admin = 0 - if(client.holder && (client.holder.rights & R_ADMIN)) + if(check_rights_for(client,R_ADMIN)) is_admin = 1 else if(stat != DEAD || istype(src, /mob/new_player)) usr << "\blue You must be observing to use this!" diff --git a/config/admin_ranks.txt b/config/admin_ranks.txt index 2a33adb3b80..67c08182b01 100644 --- a/config/admin_ranks.txt +++ b/config/admin_ranks.txt @@ -1,15 +1,15 @@ -######################################################################################## -# ADMIN RANK DEFINES # -# The format of this is very simple. Rank name goes first. # -# Rank is CASE-SENSITIVE, all punctuation will be stripped so spaces don't matter. # -# Each rank is then followed by keywords with the prefix "+". # -# These keywords represent groups of verbs and abilities which are given to that rank. # -# +@ (or +prev) is a special shorthand which adds all the rights of the rank above it. # -# Ranks with no keywords will just be given the most basic verbs and abilities ~Carn # -######################################################################################## +############################################################################################################## +# ADMIN RANK DEFINES # +# The format of this is very simple. Rank name goes first. # +# Rank is CASE-SENSITIVE, all punctuation save for '-', '_' and '@' will be stripped so spaces don't matter. # +# You can then define permissions for each rank by adding a '=' followed by keywords # +# These keywords represent groups of verbs and abilities. # +# keywords are preceded by either a '+' or a '-', + adds permissions, - takes them away. # +# +@ (or +prev) is a special shorthand which adds all the rights of the rank above it. # +# You can also specify verbs like so +/client/proc/some_added_verb or -/client/proc/some_restricted_verb # +# Ranks with no keywords will just be given the most basic verbs and abilities ~Carn # +############################################################################################################## # PLEASE NOTE: depending on config options, some abilities will be unavailable regardless if you have permission to use them! -# ALSO NOTE: this is a WorkInProgress at the moment. Most of this is just arbitrarily thrown in whatever group because LoadsaWork2Do+LittleTime. -# I'll be doing more moving around as feedback comes in. So be sure to check the notes after updates. # KEYWORDS: # +ADMIN = general admin tools, verbs etc @@ -28,13 +28,13 @@ # +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag Admin Observer -Moderator +ADMIN -Admin Candidate +@ -Trial Admin +@ +SPAWN +REJUV +VAREDIT +BAN -Badmin +@ +POSSESS +BUILDMODE +SERVER +FUN -Game Admin +@ +STEALTH +SOUNDS +DEBUG -Game Master +EVERYTHING +Moderator = +ADMIN +Admin Candidate = +@ +Trial Admin = +@ +SPAWN +REJUV +VAREDIT +BAN +Badmin = +@ +POSSESS +BUILDMODE +SERVER +FUN +Game Admin = +@ +STEALTH +SOUNDS +DEBUG +Game Master = +EVERYTHING -Host +EVERYTHING +Host = +EVERYTHING -Coder +DEBUG +VAREDIT +SERVER +SPAWN \ No newline at end of file +Coder = +DEBUG +VAREDIT +SERVER +SPAWN \ No newline at end of file diff --git a/config/admins.txt b/config/admins.txt index 121cad72d0d..47a6a1e9acf 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -1,29 +1,32 @@ -###################################################################### -# Basically, ckey goes first. Rank goes after the "-" # -# Case is not important for ckey. # -# Case IS important for the rank. However punctuation/spaces are not # -# Ranks can be anything defined in admin_ranks.txt ~Carn # -###################################################################### +############################################################################################### +# Basically, ckey goes first. Rank goes after the "=" # +# Case is not important for ckey. # +# Case IS important for the rank. # +# All punctuation (spaces etc) EXCEPT '-', '_' and '@' will be stripped from rank names. # +# Ranks can be anything defined in admin_ranks.txt # +# NOTE: if the rank-name cannot be found in admin_ranks.txt, they will not be adminned! ~Carn # +# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. # +############################################################################################### -quarxink - Game Master -tle - Game Master -xsi - Game Master -scaredofshadows - Game Master -neofite - Game Master -trubblebass - Game Master -mport2004 - Game Master -deuryn - Game Master -agouri - Game Master -errorage - Game Master -superxpdude - Game Master -petethegoat - Game Master -korphaeron - Game Master -nodrak - Game Master -carnwennan - Game Master -ikarrus - Game Master -cheridan - Game Master -giacomand - Game Master -rockdtben - Game Master -sieve - Game Master -aranclanos - Game Master -intigracy - Game Master \ No newline at end of file +quarxink = Game Master +tle = Game Master +xsi = Game Master +scaredofshadows = Game Master +neofite = Game Master +trubblebass = Game Master +mport2004 = Game Master +deuryn = Game Master +agouri = Game Master +errorage = Game Master +superxpdude = Game Master +petethegoat = Game Master +korphaeron = Game Master +nodrak = Game Master +carnwennan = Game Master +ikarrus = Game Master +cheridan = Game Master +giacomand = Game Master +rockdtben = Game Master +sieve = Game Master +aranclanos = Game Master +intigracy = Game Master \ No newline at end of file
CKEY \[+\]RANKPERMISSIONSRANKPERMISSIONSVERB-OVERRIDES
[adm_ckey] \[-\][rank][rights][D.rank.name][rights][rights2text(0," ",D.rank.adds,D.rank.subs)]