En esta página
Configuración
ChatShield se configura en plugins/ChatShield/config.yml, que el primer arranque crea con comentarios en cada clave. Editalo y corré /chatshield reload; no hace falta reiniciar salvo donde se indica. En Pro también podés cambiar cada ajuste desde la página Configuración del panel. En Free el panel puede cambiar el idioma, el tema y el color de acento, y todo lo demás se sigue pudiendo editar en el archivo.
Un valor incorrecto nunca frena el plugin: la consola indica la clave, qué se esperaba y el valor por defecto que usa en su lugar. Si el archivo directamente no es YAML válido, se siguen usando los ajustes anteriores.
Las claves marcadas como Pro solo tienen efecto con una licencia Pro. En Free se conservan, nunca se borran.
General #
| Clave | Por defecto | Qué hace |
|---|---|---|
language | en | Idioma de la consola, de los textos en el juego y del panel por defecto: en, es o es_AR. Cada jugador puede elegir el suyo con /chatshield lang. |
server-name | "My Server" | Se muestra en el panel, en los emails y en el prompt de la IA, y es parte de la etiqueta de instancia de la licencia. |
timezone | system | system o una zona horaria como America/Argentina/Buenos_Aires. Decide dónde corta cada día, la hora de los resúmenes, la purga diaria y los días del registro de chat. |
Consola #
| Clave | Por defecto | Qué hace |
|---|---|---|
console.banner | always | El banner grande al arrancar: always, first-run o never. El resumen de una línea (versión, plataforma, dirección del panel, idioma, plan) se muestra siempre. |
console.ascii-only | false | true fuerza el banner simple de #, para las consolas que muestran mal las letras de bloque. |
Captura #
Qué registra el plugin. Los comandos de ingreso, registro y contraseña nunca se capturan, pongas lo que pongas acá.
| Clave | Por defecto | Qué hace |
|---|---|---|
capture.capture-cancelled | false | También guarda y analiza los mensajes que canceló otro filtro de chat, para que los intentos de evasión se sigan viendo. |
capture.private-commands | [msg, tell, t, w, whisper, m, pm, r, reply, emsg, etell, ewhisper, er, ereply] | Comandos que se capturan como mensajes privados. |
capture.staff-commands | [sc, staffchat, ac, modchat, helperchat] | Comandos que se capturan como chat del staff. El chat del staff nunca genera detecciones de publicidad. |
capture.text-commands | [me, mail, helpop, report, broadcast, bc, say, nick, teammsg] | Otros comandos cuyo texto se captura. |
capture.denied-commands | [] | Comandos que nunca se capturan, además de la lista integrada de ingreso, registro y contraseña. Agregá los alias de tu plugin de login. |
capture.mask-after-keywords | [password, contraseña, contrasena, clave, senha] | Todo lo que viene después de una de estas palabras se guarda como [masked]. |
capture.context-messages | 10 | Líneas que se guardan antes y después de un mensaje marcado, como contexto del caso. |
Almacenamiento #
| Clave | Por defecto | Qué hace |
|---|---|---|
storage.retention-days | 30 | Días de registro de chat que se guardan. Free guarda 30 como máximo. Pro acepta cualquier valor, y 0 lo guarda para siempre. Los casos, los eventos y las sanciones se guardan de todos modos. |
storage.purge-at | "04:30" | Hora local de la purga diaria. |
Todo se guarda en un solo archivo SQLite, plugins/ChatShield/data.db. Hacé la copia de seguridad con el servidor apagado, o copiá data.db, data.db-wal y data.db-shm juntos.
Grupos y exenciones #
| Clave | Por defecto | Qué hace |
|---|---|---|
groups.provider | auto | De dónde salen los grupos de los jugadores: auto (LuckPerms; si no, Vault; si no, solo permisos), luckperms, vault o permissions. |
groups.staff-groups | [admin, mod, staff] | Grupos cuyos miembros cuentan como staff para el detector de abuso de rango. |
exempt.players | [] | Nombres o UUID que nunca generan casos. /chatshield exempt add y /chatshield exempt remove editan esta lista. |
exempt.groups | [] | Grupos cuyos miembros nunca generan casos. |
Las líneas de los jugadores exentos igual se guardan y se muestran como contexto en los casos de otros jugadores. El permiso chatshield.exempt también exime a un jugador.
Publicidad #
| Clave | Por defecto | Qué hace |
|---|---|---|
advertising.allowed | [] | Los enlaces oficiales de tu comunidad: tu sitio web, tu invitación de Discord y cualquier otra dirección, IP o nombre que sea tuyo. |
advertising:
allowed: [myserver.net, discord.gg/abc123, "play.myserver.net"]
Un mensaje que comparte uno de estos enlaces nunca se marca por eso, lo escriban como lo escriban los jugadores: con o sin https:// y www., en un subdominio, en mayúsculas, entre paréntesis o corchetes o detrás de un código de color, o escrito con palabras ("myserver punto net"). Todo lo demás se sigue marcando: otro Discord u otro sitio web, un nombre parecido, una dirección más larga (myserver.net.ru) o el mismo código en otro servicio de invitaciones (dsc.gg, discord.me).
- Escribí un host (
myserver.net) o una invitación (discord.gg/abc123). Si una entrada tiene un puerto o una query, se ignoran. - Una entrada con una ruta (tu página en una lista de servidores, como
minecraft-mp.com/server/123456) permite esa página y las que están debajo de ella, no el resto del sitio. - Un código de invitación con mayúsculas solo coincide cuando se escribe exactamente así. Escribí en minúsculas las invitaciones personalizadas.
- Un nombre solo (
myserver) permite ese nombre en cualquier dominio, así que ponelo solo si nadie más tiene un servidor con ese nombre.
Detección #
| Clave | Por defecto | Qué hace |
|---|---|---|
detection.packs | [en, es] | Paquetes de reglas que se cargan desde rules/<pack>.yml, en orden. rules/custom.yml siempre se carga al final. |
detection.case-window-minutes | 30 | Las detecciones del mismo jugador y tipo dentro de este lapso se juntan en un caso. |
detection.max-events-per-case | 200 | Después de esta cantidad de eventos, un caso deja de guardar los nuevos (igual los cuenta). |
detection.cooldown-seconds | 30 | Una coincidencia repetida dentro del cooldown igual se registra, pero no le avisa a nadie salvo que sea más grave. |
detection.reassembly | { messages: 5, seconds: 20 } | Detección de mensajes partidos: los últimos 5 mensajes de un jugador enviados en 20 segundos se unen y se revisan en busca de publicidad y datos personales. |
detection.harassment | { repeats: 3, window-minutes: 10, distress-window-seconds: 60 } | Acoso a partir de 3 insultos al mismo objetivo en 10 minutos, o por el malestar de una víctima dentro de los 60 segundos de un insulto. |
detection.spam | { similarity: 0.6, window-seconds: 30, repeats: 3 } | Spam a partir de 3 mensajes parecidos en 30 segundos. |
detection.caps | { min-letters: 12, ratio: 0.7 } | Mayúsculas cuando una línea tiene al menos 12 letras y el 70% de ellas son mayúsculas. |
detection.actions | ver abajo | Qué pasa con cada tipo de infracción y gravedad. |
detection.commands | [] | Pro. Comandos de consola que se corren cuando un caso llega a un umbral. |
Acciones #
Cada tipo y gravedad tiene una lista de acciones: log (solo guardar; va siempre implícita), notify (alerta en el juego, emails en tiempo real y una notificación en el panel) o command (Pro, corre las entradas de detection.commands que correspondan). Los tipos que no están en la lista usan default. Así viene de fábrica:
detection:
actions:
default: { low: [log], medium: [notify], high: [notify] }
advertising: { low: [notify], medium: [notify], high: [notify] }
personal_data: { low: [notify], medium: [notify], high: [notify] }
spam: { low: [log], medium: [log], high: [notify] }
caps: { low: [log], medium: [log], high: [log] }
Comandos automáticos (Pro) #
Por defecto no se sanciona nada automáticamente. Una entrada de detection.commands se corre una vez por caso, como la consola, cuando el caso llega a threshold eventos de gravedad min-severity o mayor, y solo mientras la fila de detection.actions de ese tipo y gravedad incluya command. Placeholders: {player}, {uuid}, {type}, {severity}, {case} y {server}. Usá los comandos de tu plugin de sanciones, y probalos primero a mano.
detection:
actions:
advertising: { low: [notify], medium: [notify], high: [notify, command] }
commands:
- { type: advertising, min-severity: high, threshold: 3, run: ["warn {player} Advertising (case {case})"] }
Archivos de reglas #
Las reglas están en plugins/ChatShield/rules/:
en.ymlyes.ymlson los paquetes de idioma incluidos, que se copian en el primer arranque.custom.ymltiene tus propias reglas y siempre se carga al final. Sus listas se suman a las de los paquetes, salvo que pongasmerge: replacearriba de todo.
# rules/custom.yml
version: 1
merge: append
detectors:
advertising:
allowed: [] # p. ej. [myserver.net, discord.gg/abc123]
hosts: [] # más hosts de la competencia
insult:
words: [] # más raíces de palabras
safe-words: [] # palabras que nunca tienen que marcarse
custom:
toxic-links: # aparece como "custom:toxic-links" en el panel
enabled: false
severity: medium
regex: ["\\bbit\\.ly/\\w+\\b"]
- Las palabras son raíces:
idiottambién coincide conidiotseidiotic. Terminá una entrada con!para que solo coincida la palabra entera. - Las expresiones regulares usan la sintaxis de Java y, por defecto, se comparan con el texto normalizado: en minúsculas, sin acentos y con el leetspeak deshecho. Empezá un patrón con
raw:para compararlo con el texto original. - Los patrones se revisan cuando se carga el archivo. Un patrón que podría colgarse (como
(a+)+) se rechaza, y uno que tarda más de 50 ms con una entrada hostil se desactiva y se nombra en la consola. - Un archivo de reglas con un error se informa, y las reglas anteriores siguen activas hasta que se corrija.
Alertas #
| Clave | Por defecto | Qué hace |
|---|---|---|
alerts.enabled | true | Alertas en el juego para los jugadores con chatshield.alerts, que pueden apagarlas para sí mismos con /chatshield alerts off. Solo las detecciones cuya acción incluye notify le avisan a alguien. |
alerts.min-severity | medium | La gravedad más baja que genera una alerta. |
alerts.types | [all] | Tipos de infracción que generan una alerta. |
Panel #
| Clave | Por defecto | Qué hace |
|---|---|---|
panel.enabled | true | Arranca el panel web. Con false, /chatshield password sigue funcionando, así las cuentas están listas cuando lo prendas. |
panel.bind | 127.0.0.1 | Dirección en la que escucha el panel. 127.0.0.1 significa solo esta máquina. Usá 0.0.0.0 solo detrás de HTTPS o de un proxy inverso. |
panel.port | 8765 | Puerto del panel. |
panel.base-path | "" | Sirve el panel bajo un prefijo como /chatshield, para un proxy inverso que dirige https://example.com/chatshield/ al panel. |
panel.public-url | "" | La dirección que se usa en los enlaces (consola, alertas, emails, enlaces de acceso). Definila cuando se llega al panel a través de un proxy o un dominio. |
panel.https.enabled | false | HTTPS integrado con el keystore de panel.https.keystore (keystore.p12 por defecto; PKCS12 o JKS). |
panel.behind-proxy | { enabled: false, trusted-proxies: ["127.0.0.1"] } | Confía en la dirección del cliente y el protocolo reenviados solo cuando vienen de estos proxies. |
panel.allowed-origins | [] | Pro. Sitios web que pueden usar la API del panel (modo de sitio web externo). |
panel.session-hours | 72 | Cuánto dura una sesión. |
panel.max-login-attempts | 5 | Ingresos fallidos desde una dirección para una cuenta antes del bloqueo por panel.lockout-minutes (15). |
panel.game-login.enabled | false | Deja que el staff ingrese con la contraseña del plugin de login del servidor (LoginSecurity o AuthMe). |
panel.skin-downloads | true | La página del jugador muestra la skin de cada jugador; el servidor descarga las imágenes del servidor de skins de Mojang (textures.minecraft.net). false no descarga nada y muestra una silueta. |
panel.accent | "#2EC27E" | Color de acento del panel y de los emails. |
panel.default-theme | auto | auto (sigue al dispositivo), light o dark. |
Los cambios en panel.bind, panel.port, panel.base-path y panel.https.* se aplican con un reinicio o con /chatshield reload desde la consola o el juego, no al guardar en el panel. Las recetas de configuración están en la guía del panel.
Acceso #
Qué grupos pueden ingresar al panel y qué ve cada uno.
access:
permissions-override: true
groups:
owner: { violations: [all], punishments: true, logs: true, analytics: true, settings: true, users: true, ai: true }
admin: { violations: [all], punishments: true, logs: true, analytics: true, settings: false, users: false, ai: true }
mod: { violations: [advertising, insult, harassment, discrimination, sexual, threat], punishments: true, logs: false, analytics: true, settings: false, users: false, ai: false }
- Cada entrada es un nombre de grupo, tal como figura en LuckPerms o en tu plugin de permisos de Vault.
violationses[all]o una lista de tipos de infracción; las otras claves sontrueofalse(las que faltan cuentan comofalse). - El acceso de un jugador es la suma de todos sus grupos, el principal y los heredados. Un jugador sin ningún grupo que coincida y sin ningún permiso del panel no puede ingresar.
- Free usa solo los dos primeros grupos (de fábrica,
modes el tercero). La consola lo avisa al arrancar. chatshield.admin(los operadores, por defecto) siempre ve todo.access.permissions-override(Pro con LuckPerms o Vault): los permisoschatshield.panel.*suman acceso por encima de los grupos. Sin LuckPerms ni Vault, esos permisos son la única forma de entrar, en Free y en Pro.- El alcance
settingspuede cambiar los comandos automáticos, que corren como la consola. Dáselo solo a los dueños.
Email #
| Clave | Por defecto | Qué hace |
|---|---|---|
email.enabled | false | Manda notificaciones por email. |
email.smtp.host | "" | Servidor SMTP. |
email.smtp.port | 587 | 587 para STARTTLS, 465 para SSL, 25 solo para un relay local. |
email.smtp.security | starttls | starttls, ssl o none. |
email.smtp.username, email.smtp.password | "" | Datos de acceso SMTP. La contraseña puede venir, en cambio, de la variable de entorno CS_SMTP_PASSWORD. |
email.smtp.from, email.smtp.from-name | "", "ChatShield" | Dirección y nombre del remitente. |
email.realtime-per | case | Emails en tiempo real por case (uno cuando se abre y uno cada vez que sube de gravedad) o por event. |
email.realtime-max-per-hour | 20 | Por encima de esto, un destinatario recibe en cambio un solo resumen al final de la hora. |
email.recipients | [] | Quién recibe qué (abajo). |
email:
recipients:
- { address: "[email protected]", language: en, categories: [all, digest], min-severity: medium, mode: digest, every: "daily@08:00" }
Cada destinatario tiene un idioma (en, es, es_AR), categorías (tipos de infracción, punishments, digest o all), una gravedad mínima y un modo: realtime, digest o both. Los horarios de los resúmenes son del estilo de 30m, 6h, daily@08:00, daily@08:00,20:00 o weekly@mon-08:00. Free usa solo el primer destinatario, con emails en tiempo real o un resumen diario; Pro permite cualquier cantidad de destinatarios, cualquier horario y los dos modos.
Sirve cualquier servicio SMTP: una contraseña de aplicación de Gmail o Google Workspace, Outlook o Microsoft 365, SendGrid, Mailgun, Brevo o tu propio servidor. Probalo con /chatshield email test <address>.
IA #
Apagada por defecto. Nada del plugin depende de ella.
| Clave | Por defecto | Qué hace |
|---|---|---|
ai.enabled | false | Activa las funciones de IA. |
ai.provider | anthropic | anthropic, u openai-compatible para OpenAI, OpenRouter, Groq, Ollama o LM Studio. |
ai.api-key | "" | Tu propia clave del proveedor (el uso se lo pagás al proveedor). En su lugar, la puede dar la variable de entorno CS_AI_KEY. |
ai.model | claude-opus-5-5 | Nombre del modelo que se manda al proveedor. |
ai.base-url | https://api.openai.com/v1 | Solo openai-compatible: la dirección de la API, por ejemplo un Ollama local. |
ai.max-tokens | 4096 | Presupuesto de salida. Dejalo en 4096 o más para los modelos Claude. |
ai.second-opinion | false | Pro. Revisión automática de falsos positivos en los casos nuevos de gravedad media y alta. |
ai.digest-summary | false | Pro. Un párrafo escrito por IA en los emails de resumen. |
Free permite 10 explicaciones por día; Pro no tiene límite. Una explicación o una segunda opinión manda el caso marcado y las líneas de alrededor, con las direcciones de email y los números de teléfono reemplazados por [personal data]. El párrafo del resumen (Pro) manda, en cambio, el resumen del período: sus totales, el jugador, el grupo, el tipo, la gravedad y la primera línea de evidencia de cada caso nuevo, y las sanciones; ese texto no se enmascara. Las respuestas se muestran como texto y nunca se ejecutan. Probalo con /chatshield ai test.
Licencia #
| Clave | Por defecto | Qué hace |
|---|---|---|
license.key | "" | Tu clave Pro. Normalmente se define con chatshield license activate <key> o desde el panel; en su lugar, la puede dar la variable de entorno CS_LICENSE_KEY. |
license.provider | polar | Dejalo como viene: la versión oficial ya sabe de qué tienda vienen sus claves. none deja todo en Free. |
Mirá Licencias y pago.
Actualizaciones #
| Clave | Por defecto | Qué hace |
|---|---|---|
updates.check | true | Busca versiones nuevas más o menos un minuto después del arranque y después cada 6 horas. |
updates.source | modrinth | modrinth o github; el otro queda de respaldo. |
updates.auto-download | false | Pro. Descarga las versiones nuevas automáticamente; se aplican en el próximo reinicio, solo si su firma es válida. |
updates.notify | [console, panel, staff] | Dónde avisar de una versión nueva. staff son los jugadores con chatshield.update.notify, cuando entran. |
Estadísticas de uso #
| Clave | Por defecto | Qué hace |
|---|---|---|
telemetry.enabled | true | Nos manda un pequeño informe de uso anónimo más o menos un minuto después del arranque y después una vez por hora: versiones, cantidad de jugadores (solo números), qué funciones están activas, el idioma y el plan de la licencia; nunca el chat, nombres de jugadores ni IP de jugadores. false no manda nada. También se puede editar desde el panel en Free. |
chatshield telemetry muestra los datos exactos del último informe. Qué guardamos y por cuánto tiempo: política de privacidad.
Sanciones #
LiteBans, AdvancedBan y los mutes de EssentialsX se leen directamente, y la lista de bans vanilla, que también usan los bans de Essentials, se revisa en busca de cambios. Para otros plugins de sanciones, los comandos de abajo se registran cuando el staff los escribe. La misma sanción vista dos veces en 5 segundos se registra una sola vez.
| Clave | Por defecto | Qué hace |
|---|---|---|
punishments.banlist-poll-seconds | 60 | Cada cuánto se revisan las listas de bans en busca de cambios. |
punishments.commands | ver abajo | Comandos que se registran como sanciones, por tipo. Agregá los nombres de los comandos de tu plugin a la lista que corresponda. |
punishments:
commands:
ban: [ban, eban]
tempban: [tempban, etempban]
ipban: [ipban, banip, tempipban, tempbanip]
unban: [unban, pardon, unbanip, pardon-ip]
mute: [mute, tempmute, ipmute, emute]
unmute: [unmute, eunmute]
kick: [kick, ekick]
warn: [warn, ewarn]
Avanzado #
| Clave | Por defecto | Qué hace |
|---|---|---|
advanced.intake-queue | 10000 | Líneas de chat que esperan análisis; por encima de esto, las líneas se guardan sin analizar. Necesita un reinicio completo. |
advanced.db-queue | 20000 | Cola de escritura de la base de datos. Necesita un reinicio completo. |
advanced.http-threads | 8 | Hilos que sirven el panel (al menos 4). |
advanced.debug | false | Registro detallado; /chatshield debug on y /chatshield debug off lo prenden y lo apagan hasta la próxima recarga. |
Secretos en variables de entorno #
Cuatro claves son secretos: nunca se escriben en el log, el panel solo las muestra enmascaradas y pueden venir de variables de entorno en lugar del archivo. Una variable siempre gana sobre config.yml y nunca se escribe de vuelta en él.
| Variable de entorno | Reemplaza a |
|---|---|
CS_SMTP_PASSWORD | email.smtp.password |
CS_AI_KEY | ai.api-key |
CS_LICENSE_KEY | license.key |
CS_PANEL_KEYSTORE_PASSWORD | panel.https.password |
Recargar #
/chatshield reload vuelve a leer config.yml, los archivos de reglas, los archivos de idioma, los prompts de la IA y las plantillas de email, y los aplica sin reiniciar. Si el config.yml nuevo no se puede leer, no cambia nada y se listan los errores.
- Las claves de la dirección del panel (
panel.bind,panel.port,panel.base-path,panel.https.*) yadvanced.http-threadsse aplican con un reinicio o con/chatshield reloaddesde la consola o el juego. advanced.intake-queueyadvanced.db-queuenecesitan un reinicio completo.- Nunca uses el
/reloaddel propio servidor. Para actualizar el plugin, reiniciá el servidor.