Skip to content

Commit

Permalink
Chat bans & admin cooldowns (#13248)
Browse files Browse the repository at this point in the history
* Chat bans & admin cooldowns

* tag fix

* Deadchat merged to OOC, not IC

* Apply suggestions from code review

Co-authored-by: KIBORG04 <bossmira4@gmail.com>

* Kiborg suggestions

---------

Co-authored-by: KIBORG04 <bossmira4@gmail.com>
  • Loading branch information
volas and KIBORG04 authored Jul 5, 2024
1 parent 28e90d2 commit 991f906
Show file tree
Hide file tree
Showing 33 changed files with 283 additions and 216 deletions.
55 changes: 39 additions & 16 deletions code/__DEFINES/admin.dm
Original file line number Diff line number Diff line change
@@ -1,29 +1,52 @@
//A set of constants used to determine which type of mute an admin wishes to apply:
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
//Therefore there needs to be a gap between the flags for the automute flags
#define MUTE_IC 1
#define MUTE_OOC 2
#define MUTE_PRAY 4
#define MUTE_ADMINHELP 8
#define MUTE_DEADCHAT 16
#define MUTE_MENTORHELP 32
#define MUTE_ALL 63

//Number of identical messages required to get the spam-prevention automute thing to trigger warnings and automutes
#define SPAM_TRIGGER_WARNING 5
#define SPAM_TRIGGER_AUTOMUTE 10

//Some constants for DB_Ban
// ban types
#define BANTYPE_PERMA "PERMABAN"
#define BANTYPE_TEMP "TEMPBAN"
#define BANTYPE_JOB_PERMA "JOB_PERMABAN"
#define BANTYPE_JOB_TEMP "JOB_TEMPBAN"
#define BANTYPE_CHAT_PERMA "CHAT_PERMABAN"
#define BANTYPE_CHAT_TEMP "CHAT_TEMPBAN"

var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_PERMA, BANTYPE_JOB_TEMP, BANTYPE_CHAT_PERMA, BANTYPE_CHAT_TEMP)

// bitflags for client chat bans
#define MUTE_NONE 0
#define MUTE_IC (1<<0) // say/me
#define MUTE_OOC (1<<1) // ooc/looc/ghostchat
#define MUTE_PRAY (1<<2) // pray
#define MUTE_PM (1<<3) // mentorhelp/adminhelp

// text representation for ban database
var/global/list/mute_ban_bitfield = list(
"IC" = MUTE_IC,
"OOC" = MUTE_OOC,
"PRAY" = MUTE_PRAY,
"PM" = MUTE_PM,
)

// number of identical messages required to get the spam-prevention automute thing to trigger warnings and automutes
#define SPAM_TRIGGER_WARNING 5
#define SPAM_TRIGGER_AUTOMUTE 10

#define STICKYBAN_TABLENAME "erro_stickyban"
#define STICKYBAN_CKEY_MATCHED_TABLENAME "erro_stickyban_matched_ckey"
#define STICKYBAN_CID_MATCHED_TABLENAME "erro_stickyban_matched_cid"
#define STICKYBAN_IP_MATCHED_TABLENAME "erro_stickyban_matched_ip"

// admin cooldowns
#define ADMIN_CD_IC "IC"
#define ADMIN_CD_OOC "OOC"
#define ADMIN_CD_PRAY "PRAY"
#define ADMIN_CD_PM "PM"

var/global/list/admin_cooldowns_list = list(
ADMIN_CD_IC,
ADMIN_CD_OOC,
ADMIN_CD_PRAY,
ADMIN_CD_PM,
)

#define IS_ON_ADMIN_CD(client, type) (LAZYACCESS(client.prefs.admin_cooldowns, type) > world.time)

//Please don't edit these values without speaking to Errorage first ~Carn
//Admin Permissions
#define R_BUILDMODE 1
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/modes_gameplays/blob/blobmouse.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
return

if (src.client)
if(client.prefs.muted & MUTE_IC)
if(client.prefs.muted & MUTE_IC || IS_ON_ADMIN_CD(client, ADMIN_CD_IC))
to_chat(src, "You cannot send IC messages (muted).")
return
if (client.handle_spam_prevention(message,MUTE_IC))
if (client.handle_spam_prevention(message,ADMIN_CD_IC))
return

if (stat != CONSCIOUS)
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/modes_gameplays/blob/blobs/factory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@
return

if (src.client)
if(client.prefs.muted & MUTE_IC)
if(client.prefs.muted & MUTE_IC || IS_ON_ADMIN_CD(client, ADMIN_CD_IC))
to_chat(src, "You cannot send IC messages (muted).")
return
if (client.handle_spam_prevention(message,MUTE_IC))
if (client.handle_spam_prevention(message,ADMIN_CD_IC))
return

if (stat != CONSCIOUS)
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/modes_gameplays/blob/overmind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@
return

if (src.client)
if(client.prefs.muted & MUTE_IC)
if(client.prefs.muted & MUTE_IC || IS_ON_ADMIN_CD(client, ADMIN_CD_IC))
to_chat(src, "You cannot send IC messages (muted).")
return
if (client.handle_spam_prevention(message,MUTE_IC))
if (client.handle_spam_prevention(message,ADMIN_CD_IC))
return

if (stat != CONSCIOUS)
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/modes_gameplays/cult/eminence.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@

/mob/camera/eminence/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
if(client)
if(client.prefs.muted & MUTE_IC)
if(client.prefs.muted & MUTE_IC || IS_ON_ADMIN_CD(client, ADMIN_CD_IC))
to_chat(src, "You cannot send IC messages (muted).")
return
if(!(ignore_spam || forced) && client.handle_spam_prevention(message,MUTE_IC))
if(!(ignore_spam || forced) && client.handle_spam_prevention(message,ADMIN_CD_IC))
return
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(!message)
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/megaphone.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

/obj/item/device/megaphone/attack_self(mob/living/user)
if (user.client)
if(user.client.prefs.muted & MUTE_IC)
if(user.client.prefs.muted & MUTE_IC || IS_ON_ADMIN_CD(user.client, ADMIN_CD_IC))
to_chat(src, "<span class='warning'>You cannot speak in IC (muted).</span>")
return
if(!ishuman(user))
Expand Down
8 changes: 4 additions & 4 deletions code/game/verbs/ooc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var/global/bridge_ooc_colour = "#7b804f"
to_chat(src, "<span class='red'>You have OOC muted.</span>")
return

if(prefs.muted & MUTE_OOC)
if(prefs.muted & MUTE_OOC || IS_ON_ADMIN_CD(src, ADMIN_CD_OOC))
to_chat(src, "<span class='red'>You cannot use OOC (muted).</span>")
return

Expand All @@ -45,7 +45,7 @@ var/global/bridge_ooc_colour = "#7b804f"
to_chat(src, "<span class='red'>[user_message]</span>")
return

if(handle_spam_prevention(msg,MUTE_OOC))
if(handle_spam_prevention(msg,ADMIN_CD_OOC))
return
if(findtext(msg, "byond://"))
to_chat(src, "<b>Advertising other servers is not allowed.</b>")
Expand Down Expand Up @@ -146,10 +146,10 @@ var/global/bridge_ooc_colour = "#7b804f"
if(!dooc_allowed && (mob.stat == DEAD))
to_chat(usr, "<span class='red'>OOC for dead mobs has been turned off.</span>")
return
if(prefs.muted & MUTE_OOC)
if(prefs.muted & MUTE_OOC || IS_ON_ADMIN_CD(src, ADMIN_CD_OOC))
to_chat(src, "<span class='red'>You cannot use OOC (muted).</span>")
return
if(handle_spam_prevention(msg,MUTE_OOC))
if(handle_spam_prevention(msg,ADMIN_CD_OOC))
return
if(findtext(msg, "byond://"))
to_chat(src, "<B>Advertising other servers is not allowed.</B>")
Expand Down
25 changes: 12 additions & 13 deletions code/modules/admin/DB_ban/functions.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_PERMA, BANTYPE_JOB_TEMP)


//Either pass the mob you wish to ban in the 'banned_mob' attribute, or the banckey, banip and bancid variables. If both are passed, the mob takes priority! If a mob is not passed, banckey is the minimum that needs to be passed! banip and bancid are optional.
// todo: job should be renamed as subtype or bansubtype
/datum/admins/proc/DB_ban_record(bantype, mob/banned_mob, duration = -1, reason, job = "", banckey = null, banip = null, bancid = null)

if(!check_rights(R_BAN))
Expand All @@ -12,14 +10,16 @@ var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_

var/serverip = sanitize_sql("[world.internet_address]:[world.port]")

if(!(bantype in valid_ban_types))
if(!(bantype in global.valid_ban_types))
CRASH("Unknown ban type [bantype]!")

switch(bantype)
if(BANTYPE_PERMA)
duration = -1
if(BANTYPE_JOB_PERMA)
duration = -1
if(BANTYPE_CHAT_PERMA)
duration = -1

if( !istext(reason) ) return
if( !isnum(duration) ) return
Expand Down Expand Up @@ -108,7 +108,7 @@ var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_

var/bantype_sql
if(bantype)
if(!(bantype in valid_ban_types))
if(!(bantype in global.valid_ban_types))
CRASH("Unknown ban type [bantype]!")
bantype_sql = "bantype = '[bantype]'"
else // any actual jobban then
Expand Down Expand Up @@ -386,7 +386,7 @@ var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_
cidsearch = "AND computerid LIKE '[playercid]%' "

if(dbbantype)
if(dbbantype in valid_ban_types)
if(dbbantype in global.valid_ban_types)
bantypesearch = "AND bantype = '[dbbantype]' "
else // idk if it's possible, i'm just updating legacy code
bantypesearch = "AND bantype = '[BANTYPE_PERMA]' "
Expand Down Expand Up @@ -429,6 +429,10 @@ var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])</font>"
if(BANTYPE_JOB_TEMP)
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes<br>Expires [expiration]</font>"
if(BANTYPE_CHAT_PERMA)
typedesc = "<b>CHAT BAN</b><br><font size='2'>([job])</font>"
if(BANTYPE_CHAT_TEMP)
typedesc = "<b>TEMP CHAT BAN</b><br><font size='2'>([job])<br>([duration] minutes<br>Expires [expiration]</font>"

output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center'>[typedesc]</td>"
Expand Down Expand Up @@ -473,20 +477,15 @@ var/global/list/valid_ban_types = list(BANTYPE_PERMA, BANTYPE_TEMP, BANTYPE_JOB_
var/serverip = sanitize_sql("[world.internet_address]:[world.port]")


if(!(bantype in valid_ban_types))
if(!(bantype in global.valid_ban_types))
CRASH("Unknown ban type [bantype]!")

switch(bantype)
if(BANTYPE_PERMA)
duration = -1
if(BANTYPE_JOB_PERMA)
duration = -1

//var/bantype
switch(bantype)
if(BANTYPE_PERMA)
duration = -1
if(BANTYPE_JOB_PERMA)
if(BANTYPE_CHAT_PERMA)
duration = -1

if( !istext(reason) ) return 0
Expand Down
25 changes: 16 additions & 9 deletions code/modules/admin/admin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,27 @@ var/global/BSACooldown = 0
<A href='?_src_=holder;warn=[M.ckey]'>Warn</A> |
<A href='?src=\ref[src];newban=\ref[M]'>Ban</A> |
<A href='?src=\ref[src];jobban2=\ref[M]'>Jobban</A> |
<A href='?src=\ref[src];chatban=\ref[M]'>Chatban</A> |
<A href='?src=\ref[src];notes=show;mob=\ref[M]'>Notes</A>
"}

if(M.client)
body += "| <A HREF='?src=\ref[src];sendtoprison=\ref[M]'>Prison</A><br>"
var/muted = M.client.prefs.muted
body += {"<br><b>Mute: </b>
<A class='[(muted & MUTE_IC)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_IC]'>IC</a>
<A class='[(muted & MUTE_OOC)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_OOC]'>OOC</a>
<A class='[(muted & MUTE_PRAY)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_PRAY]'>PRAY</a>
<A class='[(muted & MUTE_ADMINHELP)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_ADMINHELP]'>ADMINHELP</a>
<A class='[(muted & MUTE_MENTORHELP)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_MENTORHELP]'>MENTORHELP</a>
<A class='[(muted & MUTE_DEADCHAT)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_DEADCHAT]'>DEADCHAT</a>
<A class='[(muted & MUTE_ALL)?"red":"green"]' href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_ALL]'>ALL</a>
var/datum/preferences/pref = M.client.prefs
// these shows two states: if cooldown is active, and hint for chats if ban active
body += {"<br><b>Cooldowns: </b>
<A class='[IS_ON_ADMIN_CD(M.client, ADMIN_CD_IC)?"red":"green"]' href='?src=\ref[src];cooldown=\ref[M];type=[ADMIN_CD_IC]'>
IC[(pref.muted & MUTE_IC) ? " (BANNED)" : ""]
</a>
<A class='[IS_ON_ADMIN_CD(M.client, ADMIN_CD_OOC)?"red":"green"]' href='?src=\ref[src];cooldown=\ref[M];type=[ADMIN_CD_OOC]'>
OOC[(pref.muted & MUTE_OOC) ? " (BANNED)" : ""]
</a>
<A class='[IS_ON_ADMIN_CD(M.client, ADMIN_CD_PRAY)?"red":"green"]' href='?src=\ref[src];cooldown=\ref[M];type=[ADMIN_CD_PRAY]'>
PRAY[(pref.muted & MUTE_PRAY) ? " (BANNED)" : ""]
</a>
<A class='[IS_ON_ADMIN_CD(M.client, ADMIN_CD_PM)?"red":"green"]' href='?src=\ref[src];cooldown=\ref[M];type=[ADMIN_CD_PM]'>
PM[(pref.muted & MUTE_PM) ? " (BANNED)" : ""]
</a>
"}

body += {"<br><br>
Expand Down
64 changes: 64 additions & 0 deletions code/modules/admin/admin_cooldowns.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// admin cooldown system to temporary restrict players from doing something
// todo: attack, movement, consciousness (?) cooldowns

/proc/set_admin_cooldown(mob/M, type, time, by_who)
if(!ismob(M))
return

if(!M.client)
return

if(M.client.holder)
return

if(!(type in global.admin_cooldowns_list))
return

var/datum/preferences/P = M.client.prefs

LAZYSET(P.admin_cooldowns, type, world.time + time)

if(ismob(by_who))
to_chat(M, "<span class='warning bold'>You have been placed on [restriction2human(type)] cooldown by [by_who] for [time] minute\s!</span>")
message_admins("<span class='notice'>[key_name_admin(by_who)] has placed [key_name_admin(M)] on [type] cooldown.</span>")
log_admin("[key_name(by_who)] has placed [key_name(M)] on [type] cooldown.")
else
to_chat(M, "<span class='warning bold'>You have been placed on [restriction2human(type)] cooldown by [by_who] for [time] minute\s!</span>")
message_admins("<span class='notice'>[by_who] has placed [key_name_admin(M)] on [type] cooldown.</span>")
log_admin("[by_who] has placed [key_name(M)] on [type] cooldown.")

/proc/cancel_admin_cooldown(mob/M, type, by_who)
if(!ismob(M))
return

if(!M.client)
return

if(!(type in global.admin_cooldowns_list))
return

var/datum/preferences/P = M.client.prefs

LAZYREMOVE(P.admin_cooldowns, type)

if(ismob(by_who))
to_chat(M, "<span class='warning bold'>Your [restriction2human(type)] cooldown has been lifted.</span>")
message_admins("<span class='notice'>[key_name_admin(by_who)] has lifted [key_name_admin(M)] [type] cooldown.</span>")
log_admin("[key_name(by_who)] has lifted [key_name(M)] [type] cooldown.")
else
to_chat(M, "<span class='warning bold'>Your [restriction2human(type)] cooldown has been lifted.</span>")
message_admins("<span class='notice'>[by_who] has lifted [key_name_admin(M)] [type] cooldown.</span>")
log_admin("[by_who] has lifted [key_name(M)] [type] cooldown.")

/proc/restriction2human(type)
switch(type)
if(MUTE_IC, ADMIN_CD_IC)
. = "IC (say and emote) chats"
if(MUTE_OOC, ADMIN_CD_OOC)
. = "OOC (ooc, looc, ghostchat) chats"
if(MUTE_PRAY, ADMIN_CD_PRAY)
. = "pray chat"
if(MUTE_PM, ADMIN_CD_PM)
. = "admin and mentor chats"
else
CRASH("Unknown restriction [type]!")
Loading

0 comments on commit 991f906

Please sign in to comment.