diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 4311007cbf..890821e86e 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -109,6 +109,8 @@
var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
+ var/simultaneous_pm_warning_timeout = 100
+
var/use_recursive_explosions //Defines whether the server uses recursive or circular explosions.
var/assistant_maint = 0 //Do assistants get maint access?
@@ -393,6 +395,9 @@
if("ghost_interaction")
config.ghost_interaction = 1
+ if("simultaneous_pm_warning_timeout")
+ simultaneous_pm_warning_timeout = text2num(value) * 10
+
else
diary << "Unknown setting in configuration: '[name]'"
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 54c74b8162..1fb66c7d5e 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -37,14 +37,22 @@
//Fetching a message if needed. src is the sender and C is the target client
/client/proc/cmd_admin_pm(var/client/C, var/msg)
if(prefs.muted & MUTE_ADMINHELP)
- src << "Error: Admin-PM: You are unable to use admin PM-s (muted)."
+ src << "Error: Private-Message: You are unable to use PM-s (muted)."
return
if(!istype(C,/client))
- if(holder) src << "Error: Admin-PM: Client not found."
+ if(holder) src << "Error: Private-Message: Client not found."
else adminhelp(msg) //admin we are replying to left. adminhelp instead
return
+ if(C && C.last_pm_recieved + config.simultaneous_pm_warning_timeout > world.time && holder)
+ //send a warning to admins, but have a delay popup for mods
+ if(holder.rights & R_ADMIN)
+ src << "\red Simultaneous PMs warning: that player has been PM'd in the last [config.simultaneous_pm_warning_timeout / 10] seconds by: [C.ckey_last_pm]"
+ else
+ if(alert("That player has been PM'd in the last [config.simultaneous_pm_warning_timeout / 10] seconds by: [C.ckey_last_pm]","Simultaneous PMs warning","Continue","Cancel") == "Cancel")
+ return
+
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message to [C.key]") as text|null
@@ -63,6 +71,57 @@
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
+ var/recieve_color = "purple"
+ var/send_pm_type = ""
+ var/recieve_pm_type = "Player"
+ //usr.client.holder.rights
+
+ if(holder)
+ //mod PMs are maroon
+ //PMs sent from admins and mods display their rank
+ if(holder)
+ if( holder.rights & R_MOD )
+ recieve_color = "maroon"
+ else
+ recieve_color = "red"
+ send_pm_type = holder.rank
+ recieve_pm_type = holder.rank
+
+ else if(!C.holder)
+ src << "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden."
+ return
+
+ var/recieve_message = "[recieve_pm_type] PM from-[key_name(src, C, 1)]: [msg]"
+
+ if(holder && !C.holder)
+ recieve_message = "-- Administrator private message --\n" + recieve_message
+
+ //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
+ if(config.popup_admin_pm)
+ spawn(0) //so we don't hold the caller proc up
+ var/sender = src
+ var/sendername = key
+ var/reply = input(C, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply
+ if(C && reply)
+ if(sender)
+ C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
+ else
+ adminhelp(reply) //sender has left, adminhelp instead
+ return
+
+ C << recieve_message
+ src << "[send_pm_type] PM to-[key_name(C, src, 1)]: [msg]"
+
+ if(holder && !C.holder)
+ C.last_pm_recieved = world.time
+ C.ckey_last_pm = ckey
+
+ //play the recieving admin the adminhelp sound (if they have them enabled)
+ //non-admins shouldn't be able to disable this
+ if(C.prefs.toggles & SOUND_ADMINHELP)
+ C << 'sound/effects/adminhelp.ogg'
+
+ /*
if(C.holder)
if(holder) //both are admins
if(holder.rank == "Moderator") //If moderator
@@ -111,11 +170,13 @@
else //neither are admins
src << "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden."
return
+ */
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
//we don't use message_admins here because the sender/receiver might get it too
for(var/client/X in admins)
- if(X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient
+ //check client/X is an admin and isn't the sender or recipient
+ //only admins can see PMs
+ if(X.key!=key && X.key!=C.key && X.holder.rights & R_ADMIN)
X << "PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]: \blue [msg]" //inform X
-
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index 2675436c33..eec45594cd 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -8,6 +8,9 @@
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
+ var/last_pm_recieved = 0 //world.time of the last PM this mob recieved, so that mods/admins recieve warnings if a player is getting spammed
+ var/ckey_last_pm = ""
+
/////////
//OTHER//
/////////
diff --git a/config/config.txt b/config/config.txt
index 1b12fe6c2d..66fa621209 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -210,5 +210,10 @@ NUDGE_SCRIPT_PATH nudge.py
## Comment this to unrestrict the number of alien players allowed in the round. The number represents the number of alien players for every human player.
ALIEN_PLAYER_RATIO 0.2
+
##Remove the # to let ghosts spin chairs
#GHOST_INTERACTION
+
+#Seconds after a player recieves a PM that other admins will recieve warnings for trying to message
+SIMULTANEOUS_PM_WARNING_TIMEOUT 10
+