diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index 960f894d676f..4e4a1b3ff31c 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -226,7 +226,6 @@
if(rights & R_POSSESS) . += "[seperator]+POSSESS"
if(rights & R_PERMISSIONS) . += "[seperator]+PERMISSIONS"
if(rights & R_STEALTH) . += "[seperator]+STEALTH"
- if(rights & R_REJUVINATE) . += "[seperator]+REJUVINATE"
if(rights & R_COLOR) . += "[seperator]+COLOR"
if(rights & R_VAREDIT) . += "[seperator]+VAREDIT"
if(rights & R_SOUNDS) . += "[seperator]+SOUND"
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 121d1e305e43..09b55accf16d 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -25,7 +25,6 @@ DEFINE_BITFIELD(rights, list(
"POSSESS" = R_POSSESS,
"PERMISSIONS" = R_PERMISSIONS,
"STEALTH" = R_STEALTH,
- "REJUVENATE" = R_REJUVINATE,
"COLOR" = R_COLOR,
"VAREDIT" = R_VAREDIT,
"SOUNDS" = R_SOUNDS,
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index 86d5a11a668e..938fc9cc66ca 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -24,6 +24,7 @@
/datum/controller/configuration/proc/admin_reload()
if(IsAdminAdvancedProcCall())
+ alert_proccall("configuration admin_reload")
return
log_admin("[key_name(usr)] has forcefully reloaded the configuration from disk.")
message_admins("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.")
@@ -33,6 +34,7 @@
/datum/controller/configuration/proc/Load(_directory)
if(IsAdminAdvancedProcCall()) //If admin proccall is detected down the line it will horribly break everything.
+ alert_proccall("configuration Load")
return
if(_directory)
directory = _directory
@@ -117,6 +119,7 @@
/datum/controller/configuration/proc/full_wipe()
if(IsAdminAdvancedProcCall())
+ alert_proccall("configuration full_wipe")
return
entries_by_type.Cut()
QDEL_LIST_ASSOC_VAL(entries)
@@ -163,6 +166,7 @@
/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list())
if(IsAdminAdvancedProcCall())
+ alert_proccall("configuration LoadEntries")
return
var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename
diff --git a/code/global.dm b/code/global.dm
index c5c6bdf84066..ae03341d23c8 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -12,20 +12,19 @@
#define R_POSSESS (1<<5)
#define R_PERMISSIONS (1<<6)
#define R_STEALTH (1<<7)
-#define R_REJUVINATE (1<<8)
-#define R_COLOR (1<<9)
-#define R_VAREDIT (1<<10)
-#define R_SOUNDS (1<<11)
-#define R_SPAWN (1<<12)
-#define R_MOD (1<<13)
-#define R_MENTOR (1<<14)
-#define R_HOST (1<<15)
-#define R_PROFILER (1<<16)
-#define R_NOLOCK (1<<17)
-#define R_EVENT (1<<18)
+#define R_COLOR (1<<8)
+#define R_VAREDIT (1<<9)
+#define R_SOUNDS (1<<10)
+#define R_SPAWN (1<<11)
+#define R_MOD (1<<12)
+#define R_MENTOR (1<<13)
+#define R_HOST (1<<14)
+#define R_PROFILER (1<<15)
+#define R_NOLOCK (1<<16)
+#define R_EVENT (1<<17)
/// The sum of all other rank permissions.
-#define R_EVERYTHING ((1<<19)-1)
+#define R_EVERYTHING ((1<<18)-1)
// 512.1430 increases maximum bit flags from 16 to 24, so the following flags should be available for future changes:
//=================================================
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 36e70d311ac0..166acf528b1c 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -1,9 +1,9 @@
#ifndef OVERRIDE_BAN_SYSTEM
-//Blocks an attempt to connect before even creating our client datum thing.
+/// Blocks an attempt to connect before even creating our client datum thing.
/world/IsBanned(key,address,computer_id, type, real_bans_only=FALSE)
var/ckey = ckey(key)
- // This is added siliently. Thanks to MSO for this fix. You will see it when/if we go OS
+ /// This is added siliently. Thanks to MSO for this fix. You will see it when/if we go OS
if (type == "world")
return ..() //shunt world topic banchecks to purely to byond's internal ban system
@@ -11,28 +11,33 @@
if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address)
return //don't recheck connected clients.
- //Guest Checking
+ /// Guest Checking
if(IsGuestKey(key))
log_access("Failed Login: [key] - Guests not allowed")
message_admins("Failed Login: [key] - Guests not allowed")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
WAIT_DB_READY
- if(admin_datums[ckey] && (admin_datums[ckey].rights & R_MOD))
- return ..()
-
- if(CONFIG_GET(number/limit_players) && CONFIG_GET(number/limit_players) < GLOB.clients.len)
+ /// Staff can always connect through cap, for safety.
+ var/staff_player = FALSE
+ var/player_limit = CONFIG_GET(number/limit_players)
+ if(admin_datums[ckey])
+ staff_player = TRUE
+ if(admin_datums[ckey].rights & R_PERMISSIONS)
+ return ..()
+
+ if(!(staff_player && (player_limit && player_limit < GLOB.clients.len)))
return list("reason"="POP CAPPED", "desc"="\nReason: Server is pop capped at the moment at [CONFIG_GET(number/limit_players)] players. Attempt reconnection in 2-3 minutes.")
var/datum/entity/player/P = get_player_from_key(ckey)
- //check if the IP address is a known TOR node
+ /// check if the IP address is a known TOR node
if(CONFIG_GET(flag/ToRban) && ToRban_isbanned(address))
log_access("Failed Login: [src] - Banned: ToR")
message_admins("Failed Login: [src] - Banned: ToR")
return list("reason"="Using ToR", "desc"="\nReason: The network you are using to connect has been banned.\nIf you believe this is a mistake, please request help at [CONFIG_GET(string/banappeals)]")
- // wait for database to be ready
+ /// wait for database to be ready
. = P.check_ban(computer_id, address)
if(.)
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index fab0c24622fe..3e77fda210aa 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -226,6 +226,10 @@ var/savefile/Banlist
RemoveBan(A)
/client/proc/cmd_admin_do_ban(mob/M)
+ if(IsAdminAdvancedProcCall())
+ alert_proccall("cmd_admin_do_ban")
+ return
+
if(!check_rights(R_BAN|R_MOD)) return
if(!ismob(M)) return
@@ -248,3 +252,39 @@ var/savefile/Banlist
if(P.is_time_banned && alert(usr, "Ban already exists. Proceed?", "Confirmation", "Yes", "No") != "Yes")
return
P.add_timed_ban(reason, mins)
+
+
+
+/client/proc/cmd_do_management_ban(mob/M, nameless = TRUE, anti_staff = FALSE)
+ if(IsAdminAdvancedProcCall())
+ alert_proccall("cmd_do_management_ban")
+ return
+ if(!check_rights(R_PERMISSIONS))
+ to_chat(src, SPAN_BOLDWARNING("Warning: You do not have access to this command."))
+ return
+
+ if(!ismob(M))
+ to_chat(src, SPAN_BOLDWARNING("Warning: Mob not found."))
+ return
+
+ if(!anti_staff)
+ if(M.client && M.client.admin_holder && (M.client.admin_holder.rights & R_MOD))
+ to_chat(src, SPAN_BOLDWARNING("Warning: This command cannot execute on staff."))
+ return
+
+ if(!M.ckey)
+ to_chat(usr, SPAN_BOLDWARNING("Warning: Mob ckey for [M.name] not found."))
+ return
+ var/mob_key = M.ckey
+ var/mins = tgui_input_number(usr,"How long (in minutes)? \n 180 = 3 hours \n 1440 = 1 day \n 4320 = 3 days \n 10080 = 7 days \n 43800 = 1 Month \n 262800 = 6 Months \n Max = 1 Year","Ban time", 1440, 525599, 1)
+ if(!mins)
+ return
+ if(mins >= 525600) mins = 525599
+ var/reason = input(usr,"Reason? \n\nPress 'OK' to finalize the ban.","reason","Griefer") as message|null
+ if(!reason)
+ return
+ var/datum/entity/player/P = get_player_from_key(mob_key) // you may not be logged in, but I will find you and I will ban you
+ if(P.is_time_banned && alert(usr, "Ban already exists. Proceed?", "Confirmation", "Yes", "No") != "Yes")
+ return
+ ///Below proc needs replacing for nameless to function
+ P.add_timed_ban(reason, mins)
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index dd67a963047e..f887903a23d7 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -34,11 +34,10 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
if("permissions","rights") rights |= R_PERMISSIONS
if("possess") rights |= R_POSSESS
if("stealth") rights |= R_STEALTH
- if("rejuv","rejuvinate") rights |= R_REJUVINATE
if("color") rights |= R_COLOR
if("varedit") rights |= R_VAREDIT
if("event") rights |= R_EVENT
- if("everything","host","all") rights |= (R_HOST|R_BUILDMODE|R_ADMIN|R_BAN|R_SERVER|R_DEBUG|R_PERMISSIONS|R_POSSESS|R_STEALTH|R_REJUVINATE|R_COLOR|R_VAREDIT|R_EVENT|R_SOUNDS|R_NOLOCK|R_SPAWN|R_MOD|R_MENTOR)
+ if("everything","host","all") rights |= (R_HOST|R_BUILDMODE|R_ADMIN|R_BAN|R_SERVER|R_DEBUG|R_PERMISSIONS|R_POSSESS|R_STEALTH|R_COLOR|R_VAREDIT|R_EVENT|R_SOUNDS|R_NOLOCK|R_SPAWN|R_MOD|R_MENTOR)
if("sound","sounds") rights |= R_SOUNDS
if("nolock") rights |= R_NOLOCK
if("spawn","create") rights |= R_SPAWN
diff --git a/code/modules/admin/callproc.dm b/code/modules/admin/callproc.dm
index f84121785360..3b4241c20c53 100644
--- a/code/modules/admin/callproc.dm
+++ b/code/modules/admin/callproc.dm
@@ -72,6 +72,7 @@ GLOBAL_PROTECT(LastAdminCalledProc)
*/
/proc/HandleUserlessProcCall(user, datum/target, procname, list/arguments)
if(IsAdminAdvancedProcCall())
+ alert_proccall("HandleUserlessProcCall")
return
var/mob/proccall_handler/handler = GLOB.AdminProcCallHandler
handler.add_caller(user)
@@ -90,6 +91,7 @@ GLOBAL_PROTECT(LastAdminCalledProc)
*/
/proc/HandleUserlessSDQL(user, query_text)
if(IsAdminAdvancedProcCall())
+ alert_proccall("HandleUserlessSDQL")
return
var/mob/proccall_handler/handler = GLOB.AdminProcCallHandler
@@ -224,6 +226,10 @@ GLOBAL_PROTECT(LastAdminCalledProc)
/proc/IsAdminAdvancedProcCall()
return (GLOB.AdminProcCaller && GLOB.AdminProcCaller == usr?.client?.ckey) || (GLOB.AdminProcCallHandler && usr == GLOB.AdminProcCallHandler)
+/proc/alert_proccall(procname = "Unknown")
+ to_chat(usr, SPAN_BOLDWARNING("Warning: Force attempt has been logged."))
+ message_admins("[key_name(usr)] has attempted to execute a restricted proc. ([procname])")
+
/client/proc/callproc_datum(datum/called_datum as null|area|mob|obj|turf)
set category = "Debug"
set name = "Datum ProcCall"
diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm
index a119d4c0519f..4103d046cd40 100644
--- a/code/modules/admin/holder2.dm
+++ b/code/modules/admin/holder2.dm
@@ -129,6 +129,9 @@ you will have to do something like if(client.admin_holder.rights & R_ADMIN) your
return 0
/client/proc/deadmin()
+ if(IsAdminAdvancedProcCall())
+ alert_proccall("deadmin")
+ return
if(admin_holder)
admin_holder.disassociate()
QDEL_NULL(admin_holder)
diff --git a/code/modules/admin/player_panel/actions/management.dm b/code/modules/admin/player_panel/actions/management.dm
new file mode 100644
index 000000000000..04bb963cf067
--- /dev/null
+++ b/code/modules/admin/player_panel/actions/management.dm
@@ -0,0 +1,37 @@
+/datum/player_action/nameless_ban
+ action_tag = "nameless_ban"
+ name = "Nameless Ban"
+ permissions_required = R_PERMISSIONS
+
+/datum/player_action/nameless_ban/act(client/user, mob/target, list/params)
+ user.cmd_admin_do_ban(target)
+ return TRUE
+
+
+/datum/player_action/perma_ban
+ action_tag = "perma_ban"
+ name = "Permanent Ban"
+ permissions_required = R_PERMISSIONS
+
+/datum/player_action/perma_ban/act(client/user, mob/target, list/params)
+ user.cmd_admin_do_ban(target)
+ return TRUE
+
+/datum/player_action/ban_staff
+ action_tag = "ban_staff"
+ name = "Ban Staff"
+ permissions_required = R_PERMISSIONS
+
+/datum/player_action/ban_staff/act(client/user, mob/target, list/params)
+ user.cmd_admin_do_ban(target)
+ return TRUE
+
+
+/datum/player_action/shadowban
+ action_tag = "shadow_ban"
+ name = "Shadow Ban"
+ permissions_required = R_PERMISSIONS
+
+/datum/player_action/shadowban/act(client/user, mob/target, list/params)
+ user.cmd_admin_do_ban(target)
+ return TRUE
diff --git a/code/modules/admin/player_panel/player_panel.dm b/code/modules/admin/player_panel/player_panel.dm
index 12686e683521..64b2cdb3468d 100644
--- a/code/modules/admin/player_panel/player_panel.dm
+++ b/code/modules/admin/player_panel/player_panel.dm
@@ -565,6 +565,7 @@ GLOBAL_LIST_INIT(pp_status_flags, list(
.["is_human"] = ishuman(targetMob)
.["is_xeno"] = isxeno(targetMob)
+ .["is_manager"] = check_rights(R_PERMISSIONS, FALSE)
.["glob_status_flags"] = GLOB.pp_status_flags
.["glob_limbs"] = GLOB.pp_limbs
diff --git a/code/modules/admin/topic/topic.dm b/code/modules/admin/topic/topic.dm
index b371db087be6..1f8f4fc20f8a 100644
--- a/code/modules/admin/topic/topic.dm
+++ b/code/modules/admin/topic/topic.dm
@@ -982,7 +982,7 @@
message_admins("[key_name_admin(usr)] has sent [key_name_admin(M)] to the thunderdome. (Observer.)", 1)
else if(href_list["revive"])
- if(!check_rights(R_REJUVINATE)) return
+ if(!check_rights(R_MOD)) return
var/mob/living/L = locate(href_list["revive"])
if(!istype(L))
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 6926175c835a..4bcd845e33c7 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -616,6 +616,7 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list(
*/
/client/proc/init_verbs()
if(IsAdminAdvancedProcCall())
+ alert_proccall("init_verbs")
return
var/list/verblist = list()
var/list/verbstoprocess = verbs.Copy()
diff --git a/config/example/admin_ranks.txt b/config/example/admin_ranks.txt
index e8d13e4f24fb..87a1ceddcf6a 100644
--- a/config/example/admin_ranks.txt
+++ b/config/example/admin_ranks.txt
@@ -19,7 +19,6 @@
# +BAN = the ability to ban, jobban and fullban
# +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins
# +POSSESS = the ability to possess objects
-# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode
# +COLOR = the ability to use the OOC > "Set OOC Color - Self" verb
# +BUILD (or +BUILDMODE) = the ability to use buildmode
# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration.
diff --git a/tgui/packages/tgui/interfaces/PlayerPanel.js b/tgui/packages/tgui/interfaces/PlayerPanel.js
index 81e43423e0da..8075146e8cf9 100644
--- a/tgui/packages/tgui/interfaces/PlayerPanel.js
+++ b/tgui/packages/tgui/interfaces/PlayerPanel.js
@@ -10,6 +10,15 @@ const PAGES = [
color: 'green',
icon: 'tools',
},
+ {
+ title: 'Management',
+ component: () => ManagementActions,
+ color: 'purple',
+ icon: 'ban',
+ canAccess: (data) => {
+ return !!data.is_manager;
+ },
+ },
{
title: 'Punish',
component: () => PunishmentActions,
@@ -891,3 +900,62 @@ const PhysicalActions = (props, context) => {
);
};
+const ManagementActions = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { glob_mute_bits, client_muted } = data;
+ return (
+
+
+
+ act('nameless_ban')}
+ />
+ act('perma_ban')}
+ />
+ act('shadow_ban')}
+ />
+ act('ban_staff')}
+ />
+
+
+
+
+
+
+
+
+ );
+};