mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 20:20:33 +01:00
* Granular admin perms * Implement temporary user specific permissions menu * Restore config * Fix TESTING Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
@@ -7,9 +7,9 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
/datum/admin_rank
|
||||
var/name = "NoRank"
|
||||
var/rights = R_DEFAULT
|
||||
var/exclude_rights = 0
|
||||
var/include_rights = 0
|
||||
var/can_edit_rights = 0
|
||||
var/exclude_rights = NONE
|
||||
var/include_rights = NONE
|
||||
var/can_edit_rights = NONE
|
||||
|
||||
/datum/admin_rank/New(init_name, init_rights, init_exclude_rights, init_edit_rights)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
@@ -199,6 +199,33 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
testing(msg)
|
||||
#endif
|
||||
|
||||
/// Converts a rank name (such as "Coder+Moth") into a list of /datum/admin_rank
|
||||
/proc/ranks_from_rank_name(rank_name)
|
||||
var/list/rank_names = splittext(rank_name, "+")
|
||||
var/list/ranks = list()
|
||||
|
||||
for (var/datum/admin_rank/rank as anything in GLOB.admin_ranks)
|
||||
if (rank.name in rank_names)
|
||||
rank_names -= rank.name
|
||||
ranks += rank
|
||||
|
||||
if (rank_names.len == 0)
|
||||
break
|
||||
|
||||
if (rank_names.len > 0)
|
||||
log_config("Admin rank names were invalid: [jointext(ranks, ", ")]")
|
||||
|
||||
return ranks
|
||||
|
||||
/// Takes a list of rank names and joins them with +
|
||||
/proc/join_admin_ranks(list/datum/admin_rank/ranks)
|
||||
var/list/names = list()
|
||||
|
||||
for (var/datum/admin_rank/rank as anything in ranks)
|
||||
names += rank.name
|
||||
|
||||
return jointext(names, "+")
|
||||
|
||||
/proc/load_admins(no_update)
|
||||
var/dbfail
|
||||
if(!CONFIG_GET(flag/admin_legacy_system) && !SSdbcore.Connect())
|
||||
@@ -224,8 +251,12 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
//ckeys listed in admins.txt are always made admins before sql loading is attempted
|
||||
var/admins_text = file2text("[global.config.directory]/admins.txt")
|
||||
var/regex/admins_regex = new(@"^(?!#)(.+?)\s+=\s+(.+)", "gm")
|
||||
|
||||
while(admins_regex.Find(admins_text))
|
||||
new /datum/admins(rank_names[admins_regex.group[2]], ckey(admins_regex.group[1]), FALSE, TRUE)
|
||||
var/admin_key = admins_regex.group[1]
|
||||
var/admin_rank = admins_regex.group[2]
|
||||
new /datum/admins(ranks_from_rank_name(admin_rank), ckey(admin_key), force_active = FALSE, protected = TRUE)
|
||||
|
||||
if(!CONFIG_GET(flag/admin_legacy_system) || dbfail)
|
||||
var/datum/db_query/query_load_admins = SSdbcore.NewQuery("SELECT ckey, `rank` FROM [format_table_name("admin")] ORDER BY `rank`")
|
||||
if(!query_load_admins.Execute())
|
||||
@@ -243,7 +274,7 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
if(GLOB.admin_datums[admin_ckey] || GLOB.deadmins[admin_ckey])
|
||||
skip = 1
|
||||
if(!skip)
|
||||
new /datum/admins(rank_names[admin_rank], admin_ckey)
|
||||
new /datum/admins(ranks_from_rank_name(admin_rank), admin_ckey)
|
||||
qdel(query_load_admins)
|
||||
//load admins from backup file
|
||||
if(dbfail)
|
||||
@@ -263,30 +294,12 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
skip = TRUE
|
||||
if(skip)
|
||||
continue
|
||||
new /datum/admins(rank_names[backup_file_json["admins"]["[J]"]], ckey("[J]"))
|
||||
new /datum/admins(ranks_from_rank_name(backup_file_json["admins"]["[J]"]), ckey("[J]"))
|
||||
#ifdef TESTING
|
||||
var/msg = "Admins Built:\n"
|
||||
for(var/ckey in GLOB.admin_datums)
|
||||
var/datum/admins/D = GLOB.admin_datums[ckey]
|
||||
msg += "\t[ckey] - [D.rank.name]\n"
|
||||
msg += "\t[ckey] - [D.rank_names()]\n"
|
||||
testing(msg)
|
||||
#endif
|
||||
return dbfail
|
||||
|
||||
#ifdef TESTING
|
||||
/client/verb/changerank(newrank in GLOB.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
|
||||
|
||||
@@ -300,7 +300,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
|
||||
if(holder)
|
||||
control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
|
||||
|
||||
var/rights = holder.rank.rights
|
||||
var/rights = holder.rank_flags()
|
||||
add_verb(src, GLOB.admin_verbs_default)
|
||||
if(rights & R_BUILD)
|
||||
add_verb(src, /client/proc/togglebuildmodeself)
|
||||
@@ -754,7 +754,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
|
||||
/client/proc/togglebuildmodeself()
|
||||
set name = "Toggle Build Mode Self"
|
||||
set category = "Admin.Events"
|
||||
if (!(holder.rank.rights & R_BUILD))
|
||||
if (!(holder.rank_flags() & R_BUILD))
|
||||
return
|
||||
if(src.mob)
|
||||
togglebuildmode(src.mob)
|
||||
|
||||
@@ -10,7 +10,7 @@ GLOBAL_PROTECT(href_token)
|
||||
#define RESULT_2FA_ID 2
|
||||
|
||||
/datum/admins
|
||||
var/datum/admin_rank/rank
|
||||
var/list/datum/admin_rank/ranks
|
||||
|
||||
var/target
|
||||
var/name = "nobody's admin datum (no rank)" //Makes for better runtimes
|
||||
@@ -43,7 +43,7 @@ GLOBAL_PROTECT(href_token)
|
||||
/// A lazylist of tagged datums, for quick reference with the View Tags verb
|
||||
var/list/tagged_datums
|
||||
|
||||
/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected)
|
||||
/datum/admins/New(list/datum/admin_rank/ranks, ckey, force_active = FALSE, protected)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = " has tried to elevate permissions!"
|
||||
message_admins("[key_name_admin(usr)][msg]")
|
||||
@@ -55,21 +55,21 @@ GLOBAL_PROTECT(href_token)
|
||||
if(!ckey)
|
||||
QDEL_IN(src, 0)
|
||||
CRASH("Admin datum created without a ckey")
|
||||
if(!istype(R))
|
||||
if(!istype(ranks))
|
||||
QDEL_IN(src, 0)
|
||||
CRASH("Admin datum created without a rank")
|
||||
CRASH("Admin datum created with invalid ranks: [ranks] ([json_encode(ranks)])")
|
||||
target = ckey
|
||||
name = "[ckey]'s admin datum ([R])"
|
||||
rank = R
|
||||
name = "[ckey]'s admin datum ([join_admin_ranks(ranks)])"
|
||||
src.ranks = ranks
|
||||
admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
|
||||
href_token = GenerateToken()
|
||||
if(!CONFIG_GET(flag/forbid_admin_profiling))
|
||||
if(R.rights & R_DEBUG) //grant profile access, assuming admin profile access is enabled
|
||||
if(rank_flags() & R_DEBUG) //grant profile access, assuming admin profile access is enabled
|
||||
world.SetConfig("APP/admin", ckey, "role=admin")
|
||||
//only admins with +ADMIN start admined
|
||||
if(protected)
|
||||
GLOB.protected_admins[target] = src
|
||||
if (force_active || (R.rights & R_AUTOADMIN))
|
||||
if (force_active || (rank_flags() & R_AUTOADMIN))
|
||||
activate()
|
||||
else
|
||||
deactivate()
|
||||
@@ -166,7 +166,7 @@ GLOBAL_PROTECT(href_token)
|
||||
owner = null
|
||||
|
||||
/datum/admins/proc/check_for_rights(rights_required)
|
||||
if(rights_required && !(rights_required & rank.rights))
|
||||
if(rights_required && !(rights_required & rank_flags()))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -174,12 +174,12 @@ GLOBAL_PROTECT(href_token)
|
||||
/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
|
||||
if(!other)
|
||||
return TRUE //they have no rights
|
||||
if(rank.rights == R_EVERYTHING)
|
||||
if(rank_flags() == R_EVERYTHING)
|
||||
return TRUE //we have all the rights
|
||||
if(src == other)
|
||||
return TRUE //you always have more rights than yourself
|
||||
if(rank.rights != other.rank.rights)
|
||||
if( (rank.rights & other.rank.rights) == other.rank.rights )
|
||||
if(rank_flags() != other.rank_flags())
|
||||
if( (rank_flags() & other.rank_flags()) == other.rank_flags() )
|
||||
return TRUE //we have all the rights they have and more
|
||||
return FALSE
|
||||
|
||||
@@ -331,6 +331,28 @@ GLOBAL_PROTECT(href_token)
|
||||
confidential = TRUE,
|
||||
)
|
||||
|
||||
/// Get the rank name of the admin
|
||||
/datum/admins/proc/rank_names()
|
||||
return join_admin_ranks(ranks)
|
||||
|
||||
/// Get the rank flags of the admin
|
||||
/datum/admins/proc/rank_flags()
|
||||
var/combined_flags = NONE
|
||||
|
||||
for (var/datum/admin_rank/rank as anything in ranks)
|
||||
combined_flags |= rank.rights
|
||||
|
||||
return combined_flags
|
||||
|
||||
/// Get the permissions this admin is allowed to edit on other ranks
|
||||
/datum/admins/proc/can_edit_rights_flags()
|
||||
var/combined_flags = NONE
|
||||
|
||||
for (var/datum/admin_rank/rank as anything in ranks)
|
||||
combined_flags |= rank.can_edit_rights
|
||||
|
||||
return combined_flags
|
||||
|
||||
/datum/admins/vv_edit_var(var_name, var_value)
|
||||
return FALSE //nice try trialmin
|
||||
|
||||
|
||||
@@ -101,9 +101,7 @@
|
||||
<tr class='title'>
|
||||
<th style='width:150px;'>CKEY <a class='small' href='?src=[REF(src)];[HrefToken()];editrights=add'>\[+\]</a></th>
|
||||
<th style='width:125px;'>RANK</th>
|
||||
<th style='width:40%;'>PERMISSIONS</th>
|
||||
<th style='width:20%;'>DENIED</th>
|
||||
<th style='width:40%;'>ALLOWED TO EDIT</th>
|
||||
<th>PERMISSIONS</th>
|
||||
</tr>
|
||||
"}
|
||||
for(var/adm_ckey in GLOB.admin_datums+GLOB.deadmins)
|
||||
@@ -126,10 +124,8 @@
|
||||
|
||||
output += "<tr>"
|
||||
output += "<td style='text-align:center;'>[adm_ckey]<br>[deadminlink]<a class='small' href='?src=[REF(src)];[HrefToken()];editrights=remove;key=[adm_ckey]'>\[-\]</a><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=sync;key=[adm_ckey]'>\[SYNC TGDB\]</a>[verify_link]</td>"
|
||||
output += "<td><a href='?src=[REF(src)];[HrefToken()];editrights=rank;key=[adm_ckey]'>[D.rank.name]</a></td>"
|
||||
output += "<td><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=permissions;key=[adm_ckey]'>[rights2text(D.rank.include_rights," ")]</a></td>"
|
||||
output += "<td><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=permissions;key=[adm_ckey]'>[rights2text(D.rank.exclude_rights," ", "-")]</a></td>"
|
||||
output += "<td><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=permissions;key=[adm_ckey]'>[rights2text(D.rank.can_edit_rights," ", "*")]</a></td>"
|
||||
output += "<td><a href='?src=[REF(src)];[HrefToken()];editrights=rank;key=[adm_ckey]'>[D.rank_names()]</a></td>"
|
||||
output += "<td><a class='small' href='?src=[REF(src)];[HrefToken()];editrights=permissions;key=[adm_ckey]'>[rights2text(D.rank_flags(), " ")]</a></td>"
|
||||
output += "</tr>"
|
||||
output += "</table></div><div id='top'><b>Search:</b> <input type='text' id='filter' value='' style='width:70%;' onkeyup='updateSearch();'></div></body>"
|
||||
if(QDELETED(usr))
|
||||
@@ -160,7 +156,7 @@
|
||||
to_chat(usr, "<span class='admin prefix'>Editing the rank of this admin is blocked by server configuration.</span>", confidential = TRUE)
|
||||
return
|
||||
if(!CONFIG_GET(flag/admin_legacy_system) && CONFIG_GET(flag/protect_legacy_ranks) && task == "permissions")
|
||||
if(D.rank in GLOB.protected_ranks)
|
||||
if((D.ranks & GLOB.protected_ranks).len > 0)
|
||||
to_chat(usr, "<span class='admin prefix'>Editing the flags of this rank is blocked by server configuration.</span>", confidential = TRUE)
|
||||
return
|
||||
if(CONFIG_GET(flag/load_legacy_ranks_only) && (task == "add" || task == "rank" || task == "permissions"))
|
||||
@@ -202,7 +198,7 @@
|
||||
if("rank")
|
||||
change_admin_rank(admin_ckey, admin_key, use_db, D, legacy_only)
|
||||
if("permissions")
|
||||
change_admin_flags(admin_ckey, admin_key, use_db, D, legacy_only)
|
||||
change_admin_flags(admin_ckey, admin_key, D)
|
||||
if("activate")
|
||||
force_readmin(admin_key, D)
|
||||
if("deactivate")
|
||||
@@ -314,30 +310,81 @@
|
||||
log_admin("[old_owner] deadmined via auto-deadmin config.")
|
||||
return TRUE
|
||||
|
||||
#define RANK_DONE ":) I'm Done"
|
||||
|
||||
/datum/admins/proc/change_admin_rank(admin_ckey, admin_key, use_db, datum/admins/D, legacy_only)
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
var/datum/admin_rank/R
|
||||
|
||||
var/list/rank_names = list()
|
||||
if(!use_db || (use_db && !legacy_only))
|
||||
rank_names += "*New Rank*"
|
||||
for(R in GLOB.admin_ranks)
|
||||
if((R.rights & usr.client.holder.rank.can_edit_rights) == R.rights)
|
||||
rank_names[R.name] = R
|
||||
var/new_rank = input("Please select a rank", "New rank") as null|anything in rank_names
|
||||
if(new_rank == "*New Rank*")
|
||||
new_rank = input("Please input a new rank", "New custom rank") as text|null
|
||||
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) //duplicate our previous admin_rank but with a new name
|
||||
else
|
||||
R = new(new_rank) //blank new admin_rank
|
||||
GLOB.admin_ranks += R
|
||||
var/m1 = "[key_name_admin(usr)] edited the admin rank of [admin_key] to [new_rank] [use_db ? "permanently" : "temporarily"]"
|
||||
var/m2 = "[key_name(usr)] edited the admin rank of [admin_key] to [new_rank] [use_db ? "permanently" : "temporarily"]"
|
||||
for(var/datum/admin_rank/admin_rank as anything in GLOB.admin_ranks)
|
||||
if((admin_rank.rights & usr.client.holder.can_edit_rights_flags()) == admin_rank.rights)
|
||||
rank_names[admin_rank.name] = admin_rank
|
||||
|
||||
var/list/new_rank_names = list()
|
||||
var/list/custom_ranks = list()
|
||||
|
||||
while (TRUE)
|
||||
var/list/display_rank_names = list(RANK_DONE)
|
||||
|
||||
if (new_rank_names.len > 0)
|
||||
display_rank_names += "** SELECTED **"
|
||||
for (var/rank_name in new_rank_names)
|
||||
display_rank_names += rank_name
|
||||
display_rank_names += "---------"
|
||||
|
||||
for (var/rank_name in rank_names)
|
||||
if (!(rank_name in display_rank_names))
|
||||
display_rank_names += rank_name
|
||||
|
||||
var/next_rank = input("Please select a rank, or select [RANK_DONE] if you are finished.") as null|anything in display_rank_names
|
||||
|
||||
if (isnull(next_rank))
|
||||
return
|
||||
|
||||
if (next_rank == RANK_DONE)
|
||||
break
|
||||
|
||||
// They clicked "** SELECTED **" or something silly.
|
||||
if (!(next_rank in rank_names))
|
||||
continue
|
||||
|
||||
if (next_rank in new_rank_names)
|
||||
new_rank_names -= next_rank
|
||||
continue
|
||||
|
||||
if (next_rank == "*New Rank*")
|
||||
var/new_rank_name = input("Please input a new rank", "New custom rank") as text|null
|
||||
if (!new_rank_name)
|
||||
return
|
||||
|
||||
var/datum/admin_rank/custom_rank = rank_names[new_rank_name]
|
||||
if (isnull(custom_rank))
|
||||
if (D)
|
||||
custom_rank = new(new_rank_name, D.rank_flags())
|
||||
else
|
||||
custom_rank = new(new_rank_name)
|
||||
|
||||
GLOB.admin_ranks += custom_rank
|
||||
custom_ranks += custom_rank
|
||||
new_rank_names += new_rank_name
|
||||
|
||||
new_rank_names += next_rank
|
||||
|
||||
var/list/new_ranks = list()
|
||||
for (var/datum/admin_rank/admin_rank as anything in GLOB.admin_ranks)
|
||||
if (admin_rank.name in new_rank_names)
|
||||
new_ranks += admin_rank
|
||||
new_rank_names -= admin_rank.name
|
||||
|
||||
if (new_rank_names.len == 0)
|
||||
break
|
||||
|
||||
var/joined_rank = join_admin_ranks(new_ranks)
|
||||
var/m1 = "[key_name_admin(usr)] edited the admin rank of [admin_key] to [joined_rank] [use_db ? "permanently" : "temporarily"]"
|
||||
var/m2 = "[key_name(usr)] edited the admin rank of [admin_key] to [joined_rank] [use_db ? "permanently" : "temporarily"]"
|
||||
if(use_db)
|
||||
//if a player was tempminned before having a permanent change made to their rank they won't yet be in the db
|
||||
var/old_rank
|
||||
@@ -354,36 +401,38 @@
|
||||
else
|
||||
old_rank = query_admin_in_db.item[1]
|
||||
qdel(query_admin_in_db)
|
||||
//similarly if a temp rank is created it won't be in the db if someone is permanently changed to it
|
||||
var/datum/db_query/query_rank_in_db = SSdbcore.NewQuery(
|
||||
"SELECT 1 FROM [format_table_name("admin_ranks")] WHERE `rank` = :new_rank",
|
||||
list("new_rank" = new_rank)
|
||||
)
|
||||
if(!query_rank_in_db.warn_execute())
|
||||
qdel(query_rank_in_db)
|
||||
return
|
||||
if(!query_rank_in_db.NextRow())
|
||||
QDEL_NULL(query_rank_in_db)
|
||||
var/datum/db_query/query_add_rank = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_ranks")] (`rank`, flags, exclude_flags, can_edit_flags)
|
||||
VALUES (:new_rank, '0', '0', '0')
|
||||
"}, list("new_rank" = new_rank))
|
||||
if(!query_add_rank.warn_execute())
|
||||
|
||||
for (var/datum/admin_rank/custom_rank in custom_ranks)
|
||||
//similarly if a temp rank is created it won't be in the db if someone is permanently changed to it
|
||||
var/datum/db_query/query_rank_in_db = SSdbcore.NewQuery(
|
||||
"SELECT 1 FROM [format_table_name("admin_ranks")] WHERE `rank` = :new_rank",
|
||||
list("new_rank" = custom_rank.name)
|
||||
)
|
||||
if(!query_rank_in_db.warn_execute())
|
||||
qdel(query_rank_in_db)
|
||||
return
|
||||
if(!query_rank_in_db.NextRow())
|
||||
QDEL_NULL(query_rank_in_db)
|
||||
var/datum/db_query/query_add_rank = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_ranks")] (`rank`, flags, exclude_flags, can_edit_flags)
|
||||
VALUES (:new_rank, '0', '0', '0')
|
||||
"}, list("new_rank" = custom_rank.name))
|
||||
if(!query_add_rank.warn_execute())
|
||||
qdel(query_add_rank)
|
||||
return
|
||||
qdel(query_add_rank)
|
||||
return
|
||||
qdel(query_add_rank)
|
||||
var/datum/db_query/query_add_rank_log = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
|
||||
VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'add rank', :new_rank, CONCAT('New rank added: ', :new_rank))
|
||||
"}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "new_rank" = new_rank))
|
||||
if(!query_add_rank_log.warn_execute())
|
||||
var/datum/db_query/query_add_rank_log = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
|
||||
VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'add rank', :new_rank, CONCAT('New rank added: ', :new_rank))
|
||||
"}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "new_rank" = custom_rank.name))
|
||||
if(!query_add_rank_log.warn_execute())
|
||||
qdel(query_add_rank_log)
|
||||
return
|
||||
qdel(query_add_rank_log)
|
||||
return
|
||||
qdel(query_add_rank_log)
|
||||
qdel(query_rank_in_db)
|
||||
qdel(query_rank_in_db)
|
||||
var/datum/db_query/query_change_rank = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("admin")] SET `rank` = :new_rank WHERE ckey = :admin_ckey",
|
||||
list("new_rank" = new_rank, "admin_ckey" = admin_ckey)
|
||||
list("new_rank" = joined_rank, "admin_ckey" = admin_ckey)
|
||||
)
|
||||
if(!query_change_rank.warn_execute())
|
||||
qdel(query_change_rank)
|
||||
@@ -392,108 +441,71 @@
|
||||
var/datum/db_query/query_change_rank_log = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
|
||||
VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'change admin rank', :target, CONCAT('Rank of ', :target, ' changed from ', :old_rank, ' to ', :new_rank))
|
||||
"}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "target" = admin_ckey, "old_rank" = old_rank, "new_rank" = new_rank))
|
||||
"}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "target" = admin_ckey, "old_rank" = old_rank, "new_rank" = joined_rank))
|
||||
if(!query_change_rank_log.warn_execute())
|
||||
qdel(query_change_rank_log)
|
||||
return
|
||||
qdel(query_change_rank_log)
|
||||
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
|
||||
D.ranks = new_ranks //set the admin_rank as our rank
|
||||
D.bypass_2fa = TRUE // Another admin has cleared us
|
||||
var/client/C = GLOB.directory[admin_ckey]
|
||||
D.associate(C)
|
||||
else
|
||||
D = new(R, admin_ckey) //new admin
|
||||
D = new(new_ranks, admin_ckey) //new admin
|
||||
D.bypass_2fa = TRUE // Another admin has cleared us
|
||||
D.activate()
|
||||
message_admins(m1)
|
||||
log_admin(m2)
|
||||
|
||||
/datum/admins/proc/change_admin_flags(admin_ckey, admin_key, use_db, datum/admins/D, legacy_only)
|
||||
var/new_flags = input_bitfield(usr, "Include permission flags<br>[use_db ? "This will affect ALL admins with this rank." : "This will affect only the current admin [admin_key]"]", "admin_flags", D.rank.include_rights, 350, 590, allowed_edit_list = usr.client.holder.rank.can_edit_rights)
|
||||
if(isnull(new_flags))
|
||||
return
|
||||
var/new_exclude_flags = input_bitfield(usr, "Exclude permission flags<br>Flags enabled here will be removed from a rank.<br>Note these take precedence over included flags.<br>[use_db ? "This will affect ALL admins with this rank." : "This will affect only the current admin [admin_key]"]", "admin_flags", D.rank.exclude_rights, 350, 670, "red", usr.client.holder.rank.can_edit_rights)
|
||||
if(isnull(new_exclude_flags))
|
||||
return
|
||||
var/new_can_edit_flags = input_bitfield(usr, "Editable permission flags<br>These are the flags this rank is allowed to edit if they have access to the permissions panel.<br>They will be unable to modify admins to a rank that has a flag not included here.<br>[use_db ? "This will affect ALL admins with this rank." : "This will affect only the current admin [admin_key]"]", "admin_flags", D.rank.can_edit_rights, 350, 710, allowed_edit_list = usr.client.holder.rank.can_edit_rights)
|
||||
if(isnull(new_can_edit_flags))
|
||||
return
|
||||
var/m1 = "[key_name_admin(usr)] edited the permissions of [use_db ? " rank [D.rank.name] permanently" : "[admin_key] temporarily"]"
|
||||
var/m2 = "[key_name(usr)] edited the permissions of [use_db ? " rank [D.rank.name] permanently" : "[admin_key] temporarily"]"
|
||||
if(use_db && !legacy_only)
|
||||
var/rank_name = D.rank.name
|
||||
var/old_flags
|
||||
var/old_exclude_flags
|
||||
var/old_can_edit_flags
|
||||
var/datum/db_query/query_get_rank_flags = SSdbcore.NewQuery(
|
||||
"SELECT flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] WHERE `rank` = :rank_name",
|
||||
list("rank_name" = rank_name)
|
||||
)
|
||||
if(!query_get_rank_flags.warn_execute())
|
||||
qdel(query_get_rank_flags)
|
||||
return
|
||||
if(query_get_rank_flags.NextRow())
|
||||
old_flags = text2num(query_get_rank_flags.item[1])
|
||||
old_exclude_flags = text2num(query_get_rank_flags.item[2])
|
||||
old_can_edit_flags = text2num(query_get_rank_flags.item[3])
|
||||
qdel(query_get_rank_flags)
|
||||
var/datum/db_query/query_change_rank_flags = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("admin_ranks")] SET flags = :new_flags, exclude_flags = :new_exclude_flags, can_edit_flags = :new_can_edit_flags WHERE `rank` = :rank_name",
|
||||
list("new_flags" = new_flags, "new_exclude_flags" = new_exclude_flags, "new_can_edit_flags" = new_can_edit_flags, "rank_name" = rank_name)
|
||||
)
|
||||
if(!query_change_rank_flags.warn_execute())
|
||||
qdel(query_change_rank_flags)
|
||||
return
|
||||
qdel(query_change_rank_flags)
|
||||
var/log_message = "Permissions of [rank_name] changed from[rights2text(old_flags," ")][rights2text(old_exclude_flags," ", "-")][rights2text(old_can_edit_flags," ", "*")] to[rights2text(new_flags," ")][rights2text(new_exclude_flags," ", "-")][rights2text(new_can_edit_flags," ", "*")]"
|
||||
var/datum/db_query/query_change_rank_flags_log = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
|
||||
VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'change rank flags', :rank_name, :log)
|
||||
"}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "rank_name" = rank_name, "log" = log_message))
|
||||
if(!query_change_rank_flags_log.warn_execute())
|
||||
qdel(query_change_rank_flags_log)
|
||||
return
|
||||
qdel(query_change_rank_flags_log)
|
||||
for(var/datum/admin_rank/R in GLOB.admin_ranks)
|
||||
if(R.name != D.rank.name)
|
||||
continue
|
||||
R.rights = new_flags &= ~new_exclude_flags
|
||||
R.exclude_rights = new_exclude_flags
|
||||
R.include_rights = new_flags
|
||||
R.can_edit_rights = new_can_edit_flags
|
||||
for(var/i in GLOB.admin_datums+GLOB.deadmins)
|
||||
var/datum/admins/A = GLOB.admin_datums[i]
|
||||
if(!A)
|
||||
A = GLOB.deadmins[i]
|
||||
if (!A)
|
||||
continue
|
||||
if(A.rank.name != D.rank.name)
|
||||
continue
|
||||
var/client/C = GLOB.directory[A.target]
|
||||
A.disassociate()
|
||||
A.associate(C)
|
||||
#undef RANK_DONE
|
||||
|
||||
/datum/admins/proc/change_admin_flags(admin_ckey, admin_key, datum/admins/admin_holder)
|
||||
var/new_flags = input_bitfield(
|
||||
usr,
|
||||
"Admin rights<br>This will affect only the current admin [admin_key]",
|
||||
"admin_flags",
|
||||
admin_holder.rank_flags(),
|
||||
350,
|
||||
590,
|
||||
allowed_edit_list = usr.client.holder.can_edit_rights_flags(),
|
||||
)
|
||||
|
||||
admin_holder.disassociate()
|
||||
|
||||
if (findtext(admin_holder.rank_names(), "([admin_ckey])"))
|
||||
var/datum/admin_rank/rank = admin_holder.ranks[1]
|
||||
rank.rights = new_flags
|
||||
rank.include_rights = new_flags
|
||||
rank.exclude_rights = NONE
|
||||
rank.can_edit_rights = rank.can_edit_rights
|
||||
else
|
||||
D.disassociate()
|
||||
if(!findtext(D.rank.name, "([admin_ckey])")) //not a modified subrank, need to duplicate the admin_rank datum to prevent modifying others too
|
||||
D.rank = new("[D.rank.name]([admin_ckey])", new_flags, new_exclude_flags, new_can_edit_flags) //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
|
||||
else
|
||||
D.rank.rights = new_flags &= ~new_exclude_flags
|
||||
D.rank.include_rights = new_flags
|
||||
D.rank.exclude_rights = new_exclude_flags
|
||||
D.rank.can_edit_rights = new_can_edit_flags
|
||||
var/client/C = GLOB.directory[admin_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(m1)
|
||||
log_admin(m2)
|
||||
// Not a modified subrank, need to duplicate the admin_rank datum to prevent modifying others too.
|
||||
var/datum/admin_rank/new_admin_rank = new(
|
||||
/* init_name = */ "[admin_holder.rank_names()]([admin_ckey])",
|
||||
/* init_rights = */ new_flags,
|
||||
|
||||
// rank_flags() includes the exclude rights, so we no longer need to handle them separately.
|
||||
/* init_exclude_rights = */ NONE,
|
||||
|
||||
/* init_edit_rights = */ admin_holder.can_edit_rights_flags(),
|
||||
)
|
||||
|
||||
admin_holder.ranks = list(new_admin_rank)
|
||||
|
||||
var/log = "[key_name(usr)] has updated the admin rights of [admin_ckey] into [rights2text(new_flags)]"
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
|
||||
var/client/admin_client = GLOB.directory[admin_ckey]
|
||||
admin_holder.associate(admin_client)
|
||||
|
||||
/datum/admins/proc/remove_rank(admin_rank)
|
||||
if(!admin_rank)
|
||||
return
|
||||
for(var/datum/admin_rank/R in GLOB.admin_ranks)
|
||||
if(R.name == admin_rank && (!(R.rights & usr.client.holder.rank.can_edit_rights) == R.rights))
|
||||
if(R.name == admin_rank && (!(R.rights & usr.client.holder.can_edit_rights_flags()) == R.rights))
|
||||
to_chat(usr, "<span class='admin prefix'>You don't have edit rights to all the rights this rank has, rank deletion not permitted.</span>", confidential = TRUE)
|
||||
return
|
||||
if(!CONFIG_GET(flag/admin_legacy_system) && CONFIG_GET(flag/protect_legacy_ranks) && (admin_rank in GLOB.protected_ranks))
|
||||
@@ -539,7 +551,7 @@
|
||||
/datum/admins/proc/sync_lastadminrank(admin_ckey, admin_key, datum/admins/D)
|
||||
var/sqlrank = "Player"
|
||||
if (D)
|
||||
sqlrank = D.rank.name
|
||||
sqlrank = D.rank_names()
|
||||
var/datum/db_query/query_sync_lastadminrank = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("player")] SET lastadminrank = :rank WHERE ckey = :ckey",
|
||||
list("rank" = sqlrank, "ckey" = admin_ckey)
|
||||
|
||||
@@ -1039,7 +1039,7 @@
|
||||
if(query_check_adminban_count.NextRow())
|
||||
var/adminban_count = text2num(query_check_adminban_count.item[1])
|
||||
var/max_adminbans = MAX_ADMINBANS_PER_ADMIN
|
||||
if(check_rights(R_PERMISSIONS, show_msg = FALSE) && (rank.can_edit_rights & R_EVERYTHING) == R_EVERYTHING) //edit rights are a more effective way to check hierarchical rank since many non-headmins have R_PERMISSIONS now
|
||||
if(check_rights(R_PERMISSIONS, show_msg = FALSE) && (can_edit_rights_flags() & R_EVERYTHING) == R_EVERYTHING) //edit rights are a more effective way to check hierarchical rank since many non-headmins have R_PERMISSIONS now
|
||||
max_adminbans = MAX_ADMINBANS_PER_HEADMIN
|
||||
if(adminban_count >= max_adminbans)
|
||||
to_chat(usr, span_danger("You've already logged [max_adminbans] admin ban(s) or more. Do not abuse this function!"), confidential = TRUE)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
body += "<body>Options panel for <b>[M]</b>"
|
||||
if(M.client)
|
||||
body += " played by <b>[M.client]</b> "
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[M.client.ckey] || GLOB.deadmins[M.client.ckey]) ? "rank" : "add"];key=[M.key]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[M.client.ckey] || GLOB.deadmins[M.client.ckey]) ? "rank" : "add"];key=[M.key]'>[M.client.holder ? M.client.holder.rank_names() : "Player"]</A>\]"
|
||||
if(CONFIG_GET(flag/use_exp_tracking))
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];getplaytimewindow=[REF(M)]'>" + M.client.get_exp_living(FALSE) + "</a>\]"
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
if (!msg)
|
||||
return
|
||||
var/rank_name = holder.rank
|
||||
var/rank_name = holder.rank_names()
|
||||
var/admin_name = key
|
||||
if(holder.fakekey)
|
||||
rank_name = pick(strings("admin_nicknames.json", "ranks", "config"))
|
||||
|
||||
@@ -64,7 +64,7 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller)
|
||||
if(GLOB.admin_datums)
|
||||
for(var/ckey in GLOB.admin_datums)
|
||||
var/datum/admins/D = GLOB.admin_datums[ckey]
|
||||
dat += "[ckey] - [D.rank.name]<br>"
|
||||
dat += "[ckey] - [D.rank_names()]<br>"
|
||||
holder << browse(dat, "window=showadmins;size=600x500")
|
||||
//Buttons for debug.
|
||||
if("maint_access_engiebrig")
|
||||
|
||||
Reference in New Issue
Block a user