Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speech filter #1082

Merged
merged 8 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config/bandastation/bandastation_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,11 @@ ROUNDSTART_RACES vulpkanin

## Time in deciseconds the mob must be clientless for to be despawned by cryopod. 30 minutes by default
#CRYO_MIN_SSD_TIME 18000

## Speech filter for players

## If enabled, some words will be removed from player's messages.
# ENABLE_SPEECH_FILTER
## List of ckeys, that bypass speech filter.
# SPEECH_FILTER_BYPASS ckey
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У нас на паре так реализовано? Почему не отдельный файл...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На паре основной конфиг в .toml

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно было добавить еще один ключ в brainrot_filter.json, но не думаю, что много кому надо обходить фильтр, максимум самим стримерам

# SPEECH_FILTER_BYPASS ckey
3 changes: 3 additions & 0 deletions config/bandastation/brainrot_filter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"brainrot_filter": [""]
}
1 change: 1 addition & 0 deletions modular_bandastation/modular_bandastation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "ru_jobs/_ru_jobs.dme"
#include "security_levels/_security_levels.dme"
#include "species/_species.dme"
#include "speech_filter/_speech_filter.dme"
#include "title_screen/_title_screen.dme"
#include "translations/_translations.dme"
#include "tts/_tts.dme"
Expand Down
4 changes: 4 additions & 0 deletions modular_bandastation/speech_filter/_speech_filter.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/datum/modpack/speech_filter
name = "Фильтр речи"
desc = "Фильтрация речи игроков."
author = "gaxeer"
5 changes: 5 additions & 0 deletions modular_bandastation/speech_filter/_speech_filter.dme
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "_speech_filter.dm"

#include "code/configuration.dm"
#include "code/mob.dm"
#include "code/speech_filter.dm"
3 changes: 3 additions & 0 deletions modular_bandastation/speech_filter/code/configuration.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/datum/config_entry/flag/enable_speech_filter

/datum/config_entry/str_list/speech_filter_bypass
3 changes: 3 additions & 0 deletions modular_bandastation/speech_filter/code/mob.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/mob/living/Login()
. = ..()
AddElement(/datum/element/speech_filter, src)
85 changes: 85 additions & 0 deletions modular_bandastation/speech_filter/code/speech_filter.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#define BRAINROT_FILTER_FILE "config/bandastation/brainrot_filter.json"

/datum/element/speech_filter
element_flags = ELEMENT_DETACH_ON_HOST_DESTROY
/// what is displayed to the speaker on replace
var/static/list/brainrot_notifications = list(
"Почему у меня такой скудный словарный запас? Стоит сходить в библиотеку и прочесть книгу...",
"Что, черт побери, я несу?",
"Я в своём уме? Надо следить за языком.",
"Неужели я не могу подобрать нужных слов? Позор мне..."
)

/datum/element/speech_filter/Attach(datum/target)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE

var/mob/mob_to_censor = target
if(!mob_to_censor.client)
return ELEMENT_INCOMPATIBLE

RegisterSignal(mob_to_censor, COMSIG_MOB_SAY, PROC_REF(filter_speech), TRUE)
RegisterSignal(mob_to_censor, COMSIG_MOB_LOGOUT, PROC_REF(Detach), TRUE)

/datum/element/speech_filter/Detach(datum/source, force)
. = ..()
UnregisterSignal(source, COMSIG_MOB_SAY)
UnregisterSignal(source, COMSIG_MOB_LOGOUT)

/datum/element/speech_filter/proc/filter_speech(mob/speaker, list/speech_args)
if(!CONFIG_GET(flag/enable_speech_filter) || can_bypass_filter(speaker))
return

var/message = speech_args[SPEECH_MESSAGE]
if(!length(message))
return

if(message[1] == "*")
return

var/brainrot_regex = get_brainrot_filter_regex()
if(!brainrot_regex)
return

var/original_message = copytext(message, 1)
message = rustutils_regex_replace(message, brainrot_regex, "i", "цветочек")
if(original_message == message)
return

speech_args[SPEECH_MESSAGE] = message
addtimer(CALLBACK(speaker, TYPE_PROC_REF(/mob, emote), "drool"), 0.3 SECONDS)
to_chat(speaker, span_priorityalert(pick(brainrot_notifications)))
message_admins("[ADMIN_LOOKUPFLW(speaker)] has attempted to say forbidden word. His message was: [original_message]")
log_game("[key_name(speaker)] has attempted to say forbidden word. His message was: [original_message]")

/datum/element/speech_filter/proc/get_brainrot_filter_regex()
if(!fexists(BRAINROT_FILTER_FILE))
return

var/static/list/filters

if(!length(filters))
var/raw_filter = file2text(BRAINROT_FILTER_FILE)
if(raw_filter)
var/list/parsed_filter = safe_json_decode(raw_filter)
if(isnull(parsed_filter))
log_config("JSON parsing failure for [BRAINROT_FILTER_FILE]")
else
filters = parsed_filter["brainrot_filter"]

if(!length(filters))
return list()

var/static/brainrot_regex
if(!brainrot_regex)
var/list/unique_filters = list()
unique_filters |= filters
brainrot_regex = unique_filters.Join("|")

return brainrot_regex

/datum/element/speech_filter/proc/can_bypass_filter(mob/mob_to_check)
return mob_to_check.client.ckey in CONFIG_GET(str_list/speech_filter_bypass)

#undef BRAINROT_FILTER_FILE
Loading