Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기CV Chat: el chat de Círculo Vicioso Club, con su diseño, apps para Android y Windows, una sola cuenta para el chat, la página y el foro, y conexión en tiempo real con Discord. Basado en Haven (AGPL-3.0).
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗CV Chat es el chat de Círculo Vicioso Club: la casa propia de una comunidad que nació en Discord, con su diseño, sus apps y una sola cuenta para el chat, la página y el foro.
CV Chat funciona sobre Haven, un chat libre y autoalojado (licencia AGPL-3.0). Haven corre sin modificar sus archivos (salvo un parche pequeño, explicado abajo) y todo lo de CV Chat se suma desde afuera, dentro del mismo proceso.
English summary for Haven developers: CV Chat runs on top of Haven 4.26.4 without touching its core files. It hooks
initFerrythrough a--requirepreload to reach the samedbandio. It adds a live two-way Discord relay (including threads, edits and deletes), Discord account linking via OAuth2identify, unforgeable verified identity on relayed messages, channel access mirrored from Discord permissions, Discord-based password recovery, full-history sync and member counter channels, plus its own UI and apps. See the issues on ancsemi/Haven for the bugs and proposals that came out of this work.
| Parte | Archivo | Descripción |
|---|---|---|
| Puente en tiempo real | tools/puente/puente.js | Discord → Haven por el gateway de Discord, y Haven → Discord con un webhook por canal. Pasa mensajes, respuestas, hilos, ediciones y borrados (un mensaje de Discord que alguien borra en Haven también se borra en Discord; el bot necesita "Gestionar mensajes"), y guarda el ID de Discord de cada mensaje, así que nunca duplica. |
| Emojis como en Discord | theme/discord-plus.theme.css, tools/puente/web/historia.* | Todos los emojis (mensajes, reacciones, selector, cuadro de escribir y la tarjeta de "Tu historia") con Twemoji, el diseño que usa Discord, en cualquier dispositivo: la fuente Haven Emoji que ya trae Haven (Twemoji 15, CC-BY 4.0, © Twitter y colaboradores) pasa adelante de los emojis del sistema. De paso no hay más cuadraditos en los emojis nuevos que el sistema no conoce. |
| Invitaciones | tools/puente/invitaciones.js, tools/puente/web/login.js, tools/puente/web/aviso.js | Cada cuenta tiene su enlace (/?invita=<usuario>, botón "🤝 Invitar gente" en la tarjeta propia, para copiar o compartir). Quien entra por ahí ve " te invitó" y, al crearse la cuenta (en las primeras 48 h), queda anotado; cuenta recién cuando vincula su Discord. Da la medalla 🤝 Reclutador (sube con 3, 10 y 25) y los reclutadores de la semana salen en el resumen. |
| Un día como hoy | tools/puente/logros.js | Todos los días a las 12, en el canal del resumen: el mensaje con más reacciones de esta fecha en años anteriores (charla, no anuncios ni solo un enlace; solo canales que ve cualquiera, sin +18), con el enlace a la conversación en la app. Nunca repite un mensaje. Los emojis personalizados salen como el emoji de Discord. |
| Editar perfil como Discord ("Nitro gratis") | tools/puente/perfil.js, tools/puente/web/aviso.js | Un solo "Editar perfil" (se abra desde donde se abra), armado como el de Discord: opciones a la izquierda, vista previa en vivo al medio y "Gratis en la app vs. Discord/Nitro" a la derecha (en el celular, pantalla completa con la vista previa arriba). Usa las piezas del editor de Haven (avatar, forma, decoración del avatar = su "marco", biografía, cumpleaños, animaciones, grupos en "Más opciones"; "Personas" solo para admins, también en el servidor) y suma lo de Nitro: estilo del nombre (color, degradé y 8 fuentes), tema del perfil (degradé de dos colores en la tarjeta) y banner (imagen o GIF). Las fuentes (OFL: Fredoka, Pacifico, Orbitron, MedievalSharp, Creepster, Bebas Neue, de Fontsource) van en y se sirven en . |
theme/)Un tema de archivo de Haven con colores, tipografía y disposición parecidos a Discord. Solo cambia el aspecto: canales sin cursiva y con letra Inter, categorías sin recuadro, respuestas con línea curva, mensajes sin separadores, etiquetas DISCORD discretas, sin código de canal ni avisos de apps en la barra superior. Con la preferencia de Haven barra compacta, la barra de escribir queda con el + a la izquierda y GIF y emoji a la derecha. En el celular, el menú lateral queda como el de la app de Discord: la tarjeta del usuario abajo, sin la sección "Servidores" ni la barra de estado.
La app de Android de Haven (Google Play) es nativa y no usa temas. Para tener el tema en el celular, la página se instala como app desde Chrome ("Instalar app"); con PUENTE_TITULO configurado, esa app lleva el nombre elegido, el icono del servidor y los colores del tema (tools/puente/instalable.js). En ese caso, los carteles de bienvenida de Haven que recomiendan su app de Android y la de PC se reemplazan por uno propio para instalar esta app, en la PC y en el celular (tools/puente/web/instalar.js).
Con PUENTE_TEMA_FIJO=1, todos ven siempre el tema por defecto del servidor y no se puede elegir otro: se ocultan el botón de temas, la barra de temas del inicio de sesión y la lista de temas en Configuración (tools/puente/tema-fijo.js). El admin lo sigue cambiando para todos desde Settings → Server Branding. Además, las opciones de diseño de Configuración (disposición, densidad, accesibilidad, iconos, imágenes...) quedan solo para los administradores, y lo que elige un administrador se aplica a todos, por separado en la PC y en pantallas táctiles.
Al entrar se abre el último canal que se usó en ese navegador, en vez de la pantalla de bienvenida de Haven; la primera vez, el primero de PUENTE_CANAL_INICIO que la persona puede ver (por ejemplo general,bienvenida).
Instalación: copiar theme/discord-plus.theme.css a /opt/haven/tema/ y descargar allí la fuente Inter (OFL) de Fontsource: inter-latin-wght-normal.woff2 e inter-latin-ext-wght-normal.woff2. Están montados en deploy/docker-compose.yml. Después, en Haven: publicar el tema y elegirlo; y en Settings → Server Branding, compartirlo, junto con la barra compacta, como valor por defecto para los miembros.
patches/)import-timeout.js: evita que la importación se corte a los 2 minutos. Solo afecta a /api/import/discord/*.Los parches anteriores del importador (canales con hilos y leer 4 canales a la vez) ya vienen en Haven 4.23.
Al pasar de Haven 4.22 a 4.23: antes de arrancar la 4.23 por primera vez hay que guardar import_authors_cleared = 1 en la tabla server_settings. Esa migración de Haven le quita el dueño a todos los mensajes importados de Discord, y acá son del usuario discord-historial a propósito (de eso dependen la vinculación de cuentas y las reacciones de la gente sin vincular).
Al pasar a Haven 4.26: en el primer arranque Haven revisa todos los archivos subidos para sacarles la ubicación, y los que no puede limpiar los saca de uploads/ (dejan de verse en el chat). Con decenas de miles de imágenes traídas de Discord, que Discord ya publica sin ubicación, conviene saltear esa revisión: antes de arrancar la 4.26 por primera vez, guardar privacy_sweep = {"done":true,"full":true} en server_settings. Lo que se sube después igual se limpia al subirlo.
Requisitos: un servidor Linux con Docker, un dominio y una aplicación de Discord con su bot. En el Developer Portal:
https://TU-DOMINIO/puente/discord/callback.Pasos:
/opt/haven. Copiar deploy/docker-compose.yml y deploy/Caddyfile a /opt/haven, y poner tu dominio en el Caddyfile./opt/haven/.env a partir de deploy/env.example.docker compose up -d. Registrar tu cuenta de admin en Haven y, en Settings → Ferry, pegar el token del bot. Ferry tiene que quedar apagado, porque el puente lo reemplaza.sudo tools/guardar-secreto.sh y reiniciar: docker compose up -d.deploy/systemd/* a /etc/systemd/system/ y ejecutar systemctl enable --now haven-sync.timer haven-hilos.timer haven-backup.timer. Para la copia de seguridad hace falta configurar un remoto de rclone en tools/rclone.conf.systemctl start haven-sync.service y seguir en tools/sincronizacion.log.Los mensajes importados se guardan a nombre de un usuario técnico discord-historial (sin permisos ni contraseña). Hay que crearlo en la tabla users antes de la primera importación: así los mensajes no salen con la etiqueta del admin y el conteo de no leídos sigue siendo rápido.
AGPL-3.0, igual que Haven. Como CV Chat es una versión modificada de Haven que la gente usa por internet, la licencia pide que su código esté a disposición de quien lo use: este repositorio sirve justamente para eso.
tools/puente/vendor/fuentes/puente/fuentes/| Notificaciones de Discord | tools/puente/avisos.js, tools/puente/web/aviso.js | Haven solo avisaba de lo escrito en Haven. Ahora los mensajes que llegan desde Discord también mandan notificación a quien mencionan, a quien le responden y, con @everyone/@here, a todo el canal (con las reglas de Haven: no a quien tiene la app abierta, ni a quien silenció el canal). Y como en Discord, las notificaciones de Haven también: solo mensajes directos, menciones, respuestas y @everyone/@here, no cada mensaje del canal. El iconito de la barra de estado del celular es el logo del servidor recortado en círculo y sin fondo (Android lo pinta de un solo color). A quien tiene la cuenta vinculada y no eligió, un cartel "Activá las notificaciones" (una vez por semana si dice "Ahora no"; en iPhone solo dentro de la app instalada). |
| Entrar sin Discord | tools/puente/accesos.js | Con PUENTE_SIN_VINCULAR_VEN=publicos, las cuentas sin vincular ven los canales de Discord que ve @everyone, con los mismos permisos (lo de solo lectura en Discord, acá también). Para escribir en ellos necesitan el email confirmado, sin esperar (el cuadro de escribir dice por qué). En Discord salen como "Nombre ᶜᵛ · sin verificar". Al vincular Discord pasan a tener lo de sus roles y su historial. |
| Nombres reservados | tools/puente/identidad.js | Nadie puede crearse la cuenta ni ponerse el nombre de otra persona de la comunidad (cuentas de Haven, Discord vinculado, miembros del servidor y autores del historial). Se compara sin mayúsculas, tildes, espacios ni signos y con números parecidos a letras (0/o, 1/l/i, 3/e…). "Gana el verdadero": al vincular, las cuentas sin vincular que usaban ese nombre lo pierden. El historial solo se reclama vinculando con Discord. |
| Medallas y rachas | tools/puente/logros.js, tools/puente/web/aviso.js | En la tarjeta de perfil, debajo del nombre: 🌱 Pionero (cuentas del primer mes), 🔗 Discord, 🔥/⚡ rachas de 7 y 30 días, 💬/🗿 mil y diez mil mensajes, 🏛️ "Desde <año>", 🦉 Búho y ⭐ Destacado de la semana; y la racha encendida (días seguidos escribiendo desde Haven). Cuenta lo escrito de los dos lados. |
| Tu historia | tools/puente/logros.js, tools/puente/web/historia.* | /puente/historia (botón en la tarjeta de perfil propia): primer mensaje, total y puesto, palabras, canales, año por año, horas y días, a quién más le responde, emojis, el mensaje más reaccionado y la racha; con una tarjeta de 1080×1350 para compartir o descargar. Sin mensajes directos ni canales privados. |
| Resumen de la semana | tools/puente/logros.js | Los lunes a las 10 (hora de Argentina, PUENTE_ZONA_HORAS), el bot publica en el canal de Discord PUENTE_RESUMEN_CANAL (que-paso) lo que pasó la semana anterior: mensajes, canales más activos, el podio, el mensaje con más reacciones, rachas y quién se sumó; llega a Haven como cualquier mensaje. Sin menciones que avisen. El nombre de la comunidad en estos textos es PUENTE_COMUNIDAD (si no está, el del servidor de Discord). |
| Rol de cuenta vinculada | tools/puente/rol.js | El puente crea en Discord un rol " ✅" (separado en la lista de miembros, con color, sin permisos) y se lo da a quien vincula su cuenta; al desvincular se saca. Al conectar y cada hora repasa todos los miembros. Necesita "Gestionar roles" con el rol del bot más arriba. |
| Baneos sincronizados | tools/puente/baneos.js | Baneo en Discord = baneo en Haven de la cuenta vinculada (y al revés, con el motivo en el registro de auditoría de Discord); los desbaneos también. No borra mensajes de ningún lado, no banea admins de Haven desde Discord y, si se borra la cuenta de Haven, el baneo de Discord queda. Lo que cambió con el puente apagado se pone al día al conectar. Necesita "Banear miembros". Las expulsiones no se copian (en Haven son de un canal; la de Discord ya saca los canales). |
| Entrar con Discord | tools/puente/vincular.js, tools/puente/web/entrar.*, tools/puente/web/login.js | Botón "Entrar con Discord" (y "Crear cuenta con Discord") en la pantalla de inicio. Si ese Discord ya está vinculado, entra con un clic; si no, se crea la cuenta en un paso (con el registro de Haven: elegir el usuario, aceptar las condiciones), queda vinculada, con su historial, su foto y su email de Discord ya confirmado. Los administradores y las cuentas con verificación en dos pasos entran con contraseña. La sesión pasa por un código de un solo uso, nunca por la URL. |
| Entrar con el foro | tools/puente/foro.js, deploy/foro/cvchat.php, tools/puente/web/entrar.*, tools/puente/web/login.js, tools/puente/web/vincular.* | Lo mismo que con Discord, con la cuenta del foro (vBulletin): "Entrar con el foro" y "Crear cuenta con el foro" en el inicio, y "Conectar con el foro" en /puente/vincular. El foro y CV Chat no se conectan entre sí: el navegador va a cvchat.php en el foro, que pide iniciar sesión si hace falta, pregunta si se quiere seguir y vuelve con el usuario, la foto y el email del foro, firmado con FORO_PUENTE_SECRETO (la misma clave en /opt/foro/puente.env). Cada paso sirve una vez y por 10 minutos. Al vincular, el foro muestra con qué cuenta de CV Chat. No entran así los administradores, las cuentas con verificación en dos pasos ni quien está baneado en el foro. |
| Cuenta única | tools/puente/cuenta.js, tools/puente/web/barra.*, tools/puente/foro.js, deploy/foro/cvchat.php | Una sola sesión para la web, el chat y el foro: quien entra en cualquiera de los tres queda adentro de los tres, y "Salir" sale de los tres. La sesión es una cookie de todo el dominio (CUENTA_DOMINIO, o el de PUBLIC_URL sin el primer nombre) con un número al azar; vence a los 30 días sin usarse y se corta si cambia la contraseña o hay un ban. La barra de arriba (/puente/barra.js) es la misma en la web y en el foro: accesos a la web, el foro, el chat, la wiki y los episodios, y a la derecha el nombre y la foto. En el foro, Apache la agrega a cada página (imagen/apache-foro.conf); con la sesión del chat el foro entra solo a la cuenta del foro unida. Si no hay una, une la del mismo email (confirmado en los dos lados) o pregunta: entrar con la que ya tiene (y quedan unidas) o crear una nueva con el mismo usuario. Quien entra solo al foro queda adentro también del chat. |
| Wiki | tools/puente/wiki.js, tools/puente/web/wiki.*, deploy/sitio/ | La wiki de la web (/wiki, /wiki/<entrada>, /wiki-categorias/<categoría>), con las páginas y el diseño de la web, que web/wiki.js llena. Cualquiera con la cuenta única propone una entrada o una edición (Markdown, con fotos); queda pendiente hasta que un administrador la aprueba, viendo qué cambia. Lo de los administradores se publica directo. Nada se borra: queda el historial de cada entrada y se puede volver a una versión anterior. Los administradores ven en la barra cuántas propuestas hay por revisar. |
| Vinculación de cuentas | tools/puente/vincular.js | Botón "Conectar con Discord" (OAuth2, solo el permiso identify). Al vincular, el historial de esa persona en Discord pasa a su cuenta de Haven. Una cuenta de Discord solo puede vincularse a una de Haven. |
| Identidad verificada | tools/puente/puente.js | En Discord, los mensajes de cuentas vinculadas salen con su nombre y avatar de Discord y la línea ✅ desde Haven · @usuario (el texto se cambia con PUENTE_FIRMA), una mención real que no notifica a nadie. Las menciones escritas a mano se convierten en texto, así que la línea no se puede falsificar. Las cuentas sin vincular salen como "Nombre (Haven, sin verificar)", o no salen. |
| Accesos según Discord | tools/puente/accesos.js | En modo migración, cada cuenta vinculada ve exactamente los canales que ve en Discord, con el mismo cálculo de permisos que usa Discord (roles y permisos por canal). También copia quién puede escribir, escribir en hilos, reaccionar y adjuntar archivos en cada canal: Haven rechaza lo que Discord no permitiría y el cuadro de escribir avisa "No tenés permiso para enviar mensajes en este canal". Se actualiza en vivo con los cambios de roles, expulsiones y baneos. Bloquea la entrada por código a esos canales. |
| Recuperar contraseña con Discord | tools/puente/vincular.js | Haven no trae recuperación por email (ver la fila siguiente). Quien tiene la cuenta vinculada puede poner una contraseña nueva iniciando sesión con Discord. Por seguridad no se permite para administradores ni para cuentas con verificación en dos pasos. |
| Email de recuperación | tools/puente/email.js | Con PUENTE_RESEND_KEY (una clave de Resend con permiso solo de envío) y PUENTE_EMAIL_DE (el remitente, con un dominio verificado en Resend); con PUENTE_BREVO_KEY (una clave de API de Brevo, con el mismo dominio verificado), Brevo es el respaldo cuando Resend llega a su tope del día o falla: el registro pide un email obligatorio y manda un mail para confirmarlo; quien ya tiene cuenta ve un cartel para agregarlo (escrito a mano o el de su cuenta de Discord, que ya viene confirmado), y "¿Olvidaste tu contraseña?" manda un enlace de un solo uso que vale 1 hora. Igual que la recuperación con Discord, no vale para administradores ni cuentas con verificación en dos pasos. Con PUENTE_EMAIL_OBLIGATORIO=1, quien todavía no tiene email (salvo los invitados) no puede cerrar el cartel sin poner uno. Los emails quedan solo en la base de datos. |
| Aviso dentro de Haven | tools/puente/web/ | Muestra "Vinculá tu cuenta de Discord" en la aplicación y "¿Olvidaste tu contraseña?" en la pantalla de inicio de sesión. |
| Contadores | tools/puente/estadisticas.js | Canales "👥 -N" (con el título de la app, por ejemplo "cv-chat-80") y "🔗 discord-link-N". También copia en vivo los nombres de los canales de Discord, por ejemplo los contadores de miembros. |
| Reenvíos y avatares | tools/puente/adjuntos.js | Los mensajes reenviados en Discord se muestran como "↪ Reenviado" con el texto citado y sus adjuntos. Al vincular la cuenta, si no tiene avatar en Haven, se usa el de Discord. |
| Nombres como en Discord | tools/puente/cargar.js, tools/puente/web/aviso.js | Haven solo acepta nombres para mostrar de 2 a 20 caracteres con letras, números, espacios y "_". Acá se aceptan los mismos que en Discord: de 1 a 32 caracteres, cualquiera (sin caracteres de control), también al cambiarlo en "Editar perfil". Haven los muestra siempre como texto (se probó con nombres que llevan HTML). |
| Vistas previas como en Discord | tools/puente/embeds.js, tools/puente/web/aviso.js | El puente guarda el embed que arma Discord para cada enlace (llega con el mensaje o enseguida, de los dos lados; los mensajes viejos se le piden a Discord una vez) y CV Chat lo dibuja igual que Discord, al instante, en vez de buscar cada enlace en internet. Donde no hay embed de Discord (mensajes directos, canales sin sincronizar, o enlaces que Discord deja vacíos, como los de X) queda la vista previa de Haven. |
| Vistas previas guardadas | tools/puente/previas.js | Lo que contesta la vista previa de Haven se guarda en la base (3 días las tarjetas, 6 horas cuando no hay nada, 1 hora las del foro), así la tarjeta aparece junto con el mensaje y no un segundo después, también después de reiniciar. |
| Vista previa al compartir | tools/puente/vistas.js, tools/puente/vincular.js, tools/mazo-pixel/tapas-enlace.js | La imagen que ven WhatsApp, Telegram, X y Discord al compartir un enlace: un canal o un mensaje de CV Chat muestra los últimos mensajes con nombres y fotos (solo canales que ve cualquiera con cuenta, nunca directos, cerrados ni +18); un tema del foro, su título y el principio; un juego, su tapa. Dentro de CV Chat, los enlaces a los juegos (/app?juegos=pool) se ven con la misma tarjeta. |
| Imágenes livianas | tools/puente/miniaturas.js | En el chat, las fotos se ven en una versión reducida (WebP de hasta 960 px, hecha con sharp); al abrirlas o descargarlas, la original. Hay que instalar sharp una vez en tools/puente/vendor (ver el comentario del archivo); sin sharp se usan las originales. |
| Encabezado y lupa del celular como Discord | tools/puente/web/aviso.js, tools/puente/buscar.js | Arriba la flecha (lista de canales), "# canal ›" (su descripción) y la lupa. La lupa abre el buscador con "en: #canal" y las pestañas de Discord: Miembros (con "Invitar gente"), Multimedia, Fijados, Hilos, Enlaces y Archivos (buscar.js suma has:hilo y has:documento). Al principio de cada canal, "¡Te damos la bienvenida a #canal!"; los mensajes de bots y webhooks de Discord con la etiqueta APP; las citas con la barra gris de Discord; y en el celular, el botón para agregar otra reacción al lado de las reacciones. |
| Marketplace | tools/puente/mercado.js, tools/puente/web/aviso.js | Publicar cosas para vender (nuevas o usadas) y servicios, como el Marketplace de Facebook, solo dentro de la app: hasta 6 fotos (achicadas a WebP en /data/uploads/puente-mercado), descripción, precio en pesos, dólares o USDT (o a convenir), estado y zona. Publican las cuentas con email confirmado; duran 30 días y se renuevan. Búsqueda y filtros, Guardados, Mis publicaciones, "Escribir al vendedor" por mensaje directo, denuncias al canal de admins y ocultar (admins). Reputación atada a ventas confirmadas por las dos partes (👍/👎 y comentario, todo público), en la tarjeta de perfil y con la medalla 🏪 Vendedor confiable. La app no cobra ni participa. Se entra con el ícono de la tienda debajo del logo del servidor. |
| Apps para descargar | apps/, tools/puente/web/descargar.html, tools/puente/vincular.js | App de Android (APK, Trusted Web Activity) y de Windows (instalador .exe, Electron) que abren CV Chat en su propia ventana y se actualizan solas. Se bajan desde /puente/descargar; también están en camino a Google Play (en prueba cerrada) y a la Microsoft Store (firmada por Microsoft, sin el aviso de Windows). En iPhone se instala desde Safari. El cartel de instalar ofrece la descarga en Android y Windows. Ver apps/README.md. |
| Actualizar sola | tools/puente/vincular.js, tools/puente/web/aviso.js | La app abierta (PC y celular) se fija cada minuto, al volver a ella y al reconectarse si hay una versión nueva (/puente/version). Si cambió solo el tema, lo cambia en el momento sin recargar; si cambió el programa, recarga sola cuando no molesta: en segundo plano, o quieta 45 segundos sin nada escrito, sin llamada de voz ni ventanas abiertas. |
| Juegos: Funball | tools/puente/funball.js, tools/puente/funball-motor.js, tools/puente/web/aviso.js | El Funball de DOS (1995) para jugar online 1 contra 1, contra otra persona o contra la compu. El motor rehace, procedimiento por procedimiento, las reglas del original: los saltos, juntarse, atacar, desertar y anularse, los desbordes de más de 15, las 13 bases (agujero, chica, bomba, blindada, teletransportador, desagüe, resorte, tobogán, jabón, imán, cañón y mina), la araña con sus huevos y la compu de 4 niveles (minimax con poda, igual que la original). Se comparó jugada por jugada contra el juego original en un emulador. Tablero en perspectiva como el original, con gráficos nuevos; cada uno ve su base abajo a la derecha. Mesas abiertas, desafíos, revancha, sin límite de tiempo por jugada (como el original), aviso al celular, récord y ranking. Los dibujos (web/funball/piezas.webp, piedra.webp) y los sonidos (web/funball/sonidos/<nombre>.mp3) son propios de cada servidor y opcionales. Los tableros son los del original y van en tools/puente/funball-tableros.json, propio de cada servidor (no está en el repositorio): sin ese archivo el juego no aparece. Pestaña Funball en Juegos. |
| Juegos: Truco | tools/puente/truco.js, tools/puente/web/aviso.js | Truco argentino 1 contra 1, contra otra persona o contra la compu, a 15 o 30 puntos, con o sin flor (envido, real envido, falta envido, truco, retruco, vale cuatro, irse al mazo, pardas). El servidor reparte y arbitra: cada uno ve solo sus cartas. Mesas abiertas, desafíos por mensaje directo, revancha, chat con el rival, 2 minutos por jugada (tres veces sin jugar es abandono), aviso al celular cuando te toca, récord, ranking del mes e histórico, y la medalla 🃏 Viejo truquero con 10 victorias. Se puede mentir en el tanto: el que pierde el envido puede pedir "¡Las quiero ver en mesa!" y, si lo pescan, los puntos del envido son para el otro. Mesa con paño de fieltro, fósforos para el tanteador y sonidos de las cartas. Las partidas en curso sobreviven a un reinicio. |
| Juegos: Ajedrez | tools/puente/ajedrez.js, tools/puente/ajedrez-motor.js | Ajedrez 1 contra 1, contra otra persona o contra la compu (4 niveles), con todas las reglas (enroque, al paso, coronación, tablas por repetición, por 50 jugadas y por material). Sin reloj (se juega de a ratos y avisa cuando te toca) o con reloj (3+2, 5+0, 10+5, 15+10). Récord y ranking. |
| Juegos: GlobalSiege | tools/puente/misionrisk.js, tools/puente/misionrisk-motor.js, tools/puente/web/misionrisk/, tools/misionrisk/ | La guerra por el mundo, de 2 a 6 ejércitos, con gente del chat y la compu, con misiones secretas opcionales. Es el MissionRisk de Doug Burner (GPL v3), con las reglas pasadas al servidor y la pantalla rehecha para la app. |
| Juegos: Pool | tools/puente/pool.js, tools/puente/pool-motor.js, tools/puente/web/pool/ | Pool de 8 bolas 1 contra 1, contra otra persona o contra la compu, inspirado en el viejo Yahoo! Pool (con gráficos, física y código propios). El servidor simula cada tiro y les manda a los dos el recorrido de las bolas, así los dos ven lo mismo y nadie puede hacer trampa. Apuntar arrastrando sobre la mesa, barra de fuerza, bola en mano, controles adaptados al celular y los tiros del rival un poco más lentos para seguirlos. Los sonidos y la tapa son propios de cada servidor. |
| Juegos: la sala | tools/puente/web/aviso.js, tools/puente/chat-partida.js, tools/puente/juegos-aviso.js, tools/puente/juegos-estadisticas.js | Una biblioteca como la de Steam, con la tapa de cada juego. Mesas abiertas, desafíos, revancha, partidas amistosas, chat con el rival dentro de la partida (temporal: se borra al cerrar la mesa) y un aviso en #que-paso cuando alguien arma una mesa abierta. Se entra con el ícono del joystick. Los administradores ven qué se juega, cuánto y cómo terminan las partidas. |
| Jugar sin cuenta | tools/puente/web/juegos.*, tools/puente/web/afuera.js, tools/puente/web/login.js | La página de los juegos tiene su propio dominio (juegos.<dominio>) y se ve sin cuenta: muestra los juegos y las mesas que esperan rival. Quien abre un enlace a un juego sin sesión elige un nombre de invitado y juega (con la cuenta de invitado de Haven, que no ve canales ni la voz). Las partidas con invitados cuentan como amistosas. |
| Está escribiendo | tools/puente/escribiendo.js, tools/puente/web/aviso.js | Como en Discord: tres puntitos que laten y "Fulano está escribiendo…" (o "Fulano y Mengano…", "Varias personas…"), también con quienes escriben en Discord (con su nombre de la app si vincularon). Desde la app, en Discord se ve que el bot está escribiendo (Discord no deja mostrar el nombre de otra persona). Los mensajes leídos no se pueden sincronizar: Discord no deja que un bot marque canales como leídos para otra persona. |
| Enlaces a mensajes | tools/puente/enlaces.js, tools/puente/web/aviso.js | "Copiar enlace del mensaje" en el menú del mensaje (PC y celular), en todos los canales. Tocar un enlace a un mensaje o canal, de CV Chat o de Discord, lo abre en CV Chat mismo (también dentro de un hilo), y esos enlaces se ven como "#canal › mensaje", como en Discord. Al pasar a Discord, el puente cambia los enlaces de CV Chat por los del mismo mensaje en Discord. |
| Un nombre por persona | tools/puente/nombres.js, tools/nombres-vinculados.js | En las cuentas vinculadas, el nombre que se ve en CV Chat es el nombre para mostrar de Discord, exacto (emojis, puntos y símbolos incluidos), salvo que la persona se haya puesto uno propio en CV Chat. Todos sus mensajes, también los que escribió en Discord, se ven con ese nombre, como en Discord. Si cambia su nombre en Discord, se actualiza. El script lo aplica una vez a las cuentas que ya estaban vinculadas (con --aplicar; sin eso solo muestra lo que haría). |
| Stickers | tools/puente/stickers.js | Copia los stickers del servidor de Discord a los de Haven (un paquete con el nombre del servidor) al conectarse y cada 6 horas: los nuevos se agregan, los renombrados se renombran y los borrados salen del selector. Un sticker mandado en Discord se ve como sticker en Haven (antes ese mensaje no llegaba, porque no tenía texto). |
| Sincronización completa | tools/sincronizar-discord.js | Importa todo el historial (canales, hilos y foros, con categorías y orden) y luego trae solo lo nuevo, cada 10 minutos, como respaldo del puente. Guarda de a 100 mensajes, así que gasta poca memoria. |
| Menciones | tools/puente/adjuntos.js, tools/menciones-discord.js | Las menciones de Discord (<@id>, <#id>, <@&id>) se muestran como @usuario de Haven si la cuenta está vinculada, @Nombre si no, #canal y @rol. El puente lo hace con los mensajes nuevos; el script, una vez, con el historial importado (guarda el texto original para poder deshacerlo). |
| Hilos de la importación oficial | tools/hilos-discord.js | Convierte en hilos de verdad los canales sueltos que crea el importador de Haven, y marca como privados los canales que eran privados en Discord. |
| Control de accesos | tools/auditoria-accesos.js | Una vez al día recalcula con los datos de Discord quién puede ver cada canal y lo compara con Haven: avisa en el canal de admins si un canal de Discord es público, si hay alguien sin vincular adentro o si alguien ve un canal que en Discord no puede ver. |
| El foro adentro del chat | tools/puente/foro-lector.js, tools/puente/web/foro-vivo.js, deploy/foro/lector/ | El foro (vBulletin) se abre dentro de CV Chat con su botón, y los enlaces a la wiki o la web también. Un lector del foro que solo lee lo público avisa en #que-paso de cada tema nuevo, y un enlace a un tema se ve en el chat con su conversación (el primer mensaje y las últimas respuestas). El foro se actualiza solo, como un chat: las respuestas nuevas aparecen sin recargar. |
| Foro y CV Chat unidos | tools/puente/foro-servicio.js, deploy/foro/servicio/ | Para las cuentas unidas: el mismo avatar y el mismo nombre en los dos lados (gana el último cambio), las notificaciones del foro llegan a CV Chat (cartelito o notificación del teléfono) y los mensajes privados del foro se leen desde CV Chat. La compra y venta del foro quedó de archivo: el Marketplace es el único lugar (foro-mercado.js, apagado). |
| Campanita | tools/puente/campana.js, tools/puente/web/barra.js | Una sola campanita, en la barra de la web, el foro y la app, con las respuestas, citas y menciones del foro y las de CV Chat. |
| Portada para los que llegan | tools/puente/portada.js, tools/puente/web/login.js | La pantalla de entrar muestra lo que está pasando: cuántos hay conectados, los últimos mensajes de #círculo-vicioso, las mesas de juegos que esperan rival, lo último del Marketplace y los temas del foro con movimiento. Solo lo que ya es público. Ofrece "Jugar como invitado" y "Ver el Marketplace". |
| Marketplace en la web | tools/puente/mercado.js, tools/puente/web/afuera.js, deploy/sitio/ | El Marketplace también tiene su página (marketplace.<dominio>), que se ve sin cuenta. "Escribirle" al vendedor crea la cuenta y vuelve a la publicación dentro del chat. |
| Guardados | tools/puente/guardados.js | Como los marcadores de X: cada uno guarda mensajes desde el menú del mensaje y los ve en su sección "Guardados". Nadie más ve qué guardó. |
| Actividad | tools/puente/actividad.js | Lo mejor de la semana (los mensajes con más reacciones, solo de los canales que la persona ve) y el ranking del mes (quién escribió más y quién recibió más reacciones, solo en los canales abiertos). |
| Reacciones en vivo | tools/puente/reacciones.js | Las reacciones pasan entre Discord y CV Chat al momento. Las de una cuenta vinculada aparecen como suyas; las de una sin vincular, a nombre del usuario técnico "Discord". |
| Leído en todos lados | tools/puente/leidos.js | Lo que se lee en un dispositivo (el navegador, el celular, la PC) deja de figurar como no leído en los otros que están abiertos. |
| Denunciar un mensaje | tools/puente/denuncias.js | Desde el menú del mensaje: les llega a los administradores con el motivo y el enlace. En los mensajes privados cifrados, el servidor no puede leer el texto: lo manda quien denuncia. |
| Mensajes privados cifrados | tools/puente/cifrado.js, tools/puente/web/aviso.js | Cifrado de punta a punta para todos, sin configurar nada: las claves se crean en cada dispositivo y un dispositivo nuevo recibe el secreto de otro dispositivo abierto de la misma cuenta (ECDH). El servidor solo pasa los datos de un lado al otro y no puede leerlos. |
| Código por email en cada dispositivo nuevo | tools/puente/dospasos.js, tools/puente/web/codigo.js | Verificación en dos pasos para todos: al entrar desde un dispositivo nuevo (a la web, el chat o el foro) llega un código por email, y el dispositivo queda recordado 30 días. Quien usa la app de códigos de Haven sigue con esa. |
| El equipo con dos pasos | tools/puente/equipo.js | Los administradores y moderadores tienen que tener la verificación en dos pasos prendida: si no, quedan como miembros comunes hasta que la prenden, y ahí recuperan lo que tenían. |
| Solo la app de CV Chat | tools/puente/llave.js | La conexión en vivo solo se abre desde la página de CV Chat (la web y las apps, que son esa misma página). Otras apps que hablan con Haven no se conectan. |
| Textos con voseo | tools/puente/voseo.js | Los textos de Haven en español pasan del tú al vos ("Hacé clic", "¿Qué querés preguntar?") y se traduce lo que Haven dejó en inglés. |
| La mudanza | tools/puente/mudanza.js, tools/puente/mudanza-plan.js | A quien escribe en Discord sin cuenta vinculada, el bot le escribe por privado una sola vez con cómo vincularla. Y un cronograma con fecha que el servidor cumple solo (anuncios, mensajes privados, emails y, al final, Discord en solo lectura); se sigue y se ajusta desde Admin → Mudanza. |
| Estadísticas de uso | tools/puente/uso.js, tools/puente/medidas.js, tools/puente/panel-estadisticas.js, tools/puente/origenes.js, tools/puente/presencia.js | Para los administradores, todo propio (sin servicios de afuera) y en totales por día: cuánto tiempo se usa CV Chat y en qué sección, nuevos miembros y de dónde llegan (X, WhatsApp, Google, una invitación…), retención, el termómetro de la mudanza, horas y canales, funciones más usadas, errores y velocidad por dispositivo, y desde dónde entra cada uno (Android, PC, iPhone, navegador). Nada de lo que se escribe ni de lo que se lee. |
| Informe por mail | tools/puente/informe.js | Los lunes, el resumen de la semana por mail a los administradores, y una alerta diaria si algo se cae de golpe (nadie se registra, muchos más errores o mucha menos gente que de costumbre). |
| Vigía de la sincronización | tools/puente/vigia.js | Avisa a los administradores apenas algo puede cortar el puente, por ejemplo un permiso que le falta al bot en un canal, y dice qué tildar. |
| Sin Brotli | tools/puente/sin-brotli.js | Protección contra una falla de Node.js con respuestas comprimidas con Brotli (corregida en Node 22.23.4 y Haven 4.26.4). Queda como segunda barrera: los pedidos a otros sitios no aceptan Brotli. |
| Invitación a la prueba de Google Play | tools/puente/invitar-play.js | Script que se corre a mano para invitar por mail, de a pocos por día, a las cuentas con email confirmado a probar la app de Google Play. A cada cuenta le llega una sola vez. |
| Copias de seguridad | tools/backup.sh | Copia diaria de la base de datos (consistente aunque Haven esté funcionando) y de la configuración, subida con rclone. |