
RecordingArchiver
Archiva grabaciones por partida e incursión y prepara discos desde una consola física junto a la tele, con accesos F7/F8 y control de cobros.Recording Archiver
Conserva automáticamente los archivos disponibles en la carpeta temporal Rec de Content Warning. Organiza por partida e incursión y mantiene versiones de clips, vídeos completos y auxiliares. Antes de una limpieza o sustitución verificada del juego, traslada la fuente fuera de Rec, en su misma unidad; el worker hace después la copia persistente y verifica sus bytes. No elimina grabaciones ni reescribe su contenido.
Instalación con r2modman
- Selecciona Content Warning y un perfil de pruebas. Instala BepInExPack 5.4.2305 si no está instalado.
- En Settings, busca la opción Import local mod e importa
RecordingArchiver-1.6.1.zip. Usa nombre RecordingArchiver y versión 1.6.1 si el gestor los pide. Retira la versión anterior del perfil para evitar dos copias del plugin. - Inicia con Start modded. Busca
Recording Archiver 1.6.1 loaded,Pre-delete and pre-overwrite retention hooks activeyArchive worker readyenBepInEx/LogOutput.log. La carga del plugin no confirma por sí sola que estén activos la protección y el destino.
La importación local depende de la versión del gestor; si no ofrece importar ZIP, crea una carpeta BepInEx/plugins/RecordingArchiver en el perfil y copia allí las dos DLL propias de la carpeta equivalente del ZIP.
Instalación manual: instala BepInEx compatible y copia RecordingArchiver.dll y RecordingArchiver.Core.dll juntas a BepInEx/plugins/RecordingArchiver. No copies DLL del juego. Para archivar basta instalarlo en el cliente interesado. Para preparar discos compartidos desde el terminal, todos los jugadores de la sala necesitan esta versión y los clips correspondientes.
Terminal y discos
Pulsa Ctrl+O para abrir en Windows la carpeta de partidas y grabaciones configurada en OutputDirectory. Funciona también fuera de una partida y con el terminal desactivado. Puedes cambiar la tecla en [Shortcuts] OpenArchiveFolderShortcut; None desactiva el atajo. Por defecto se usa Ctrl izquierdo. Los atajos admiten combinaciones en la configuración BepInEx: por ejemplo, U + LeftControl o U + RightControl + LeftShift. El valor antiguo OpenArchiveFolderKey deja de utilizarse. F7, F8, F9 y F10 quedan libres. La carpeta se crea si todavía no existe. También está disponible el botón Carpeta de partidas dentro del terminal.
En la superficie aparece una consola física junto a la estación de la tele. Apunta a ella y usa la interacción normal del juego: muestra «Abrir archivo de grabaciones» junto a la tecla de interacción configurada (E por defecto) y el resaltado nativo. Ctrl+U mantiene el acceso rápido desde las proximidades del equipo de subida. Ambos accesos abren la misma pantalla y respetan las mismas restricciones.
La consola es estática y local, sin objeto recogible ni PhotonView. Cada cliente con el mod genera una única instancia para su escena. Se busca una superficie próxima a la base de la tele, con espacio suficiente y una altura similar; se retira al salir o desaparecer la estación. Si no hay una ubicación libre y apoyada, no se genera una consola flotante y Ctrl+U sigue disponible. La colocación final y la apertura con E en una partida real quedan pendientes de tus pruebas manuales; la integración automatizada y sus límites figuran en docs/TESTING.md.
El terminal navega por incursión → jugador → clips de la partida actual. I_001 incluye la superficie inicial, la primera bajada y la superficie al volver. I_002 empieza al entrar en la segunda bajada; la superficie entre bajadas permanece asociada a la anterior. Al elegir un jugador puedes preparar Todos seguidos o Clip 1, Clip 2…, numerados dentro de su incursión. Cada clip aparece una sola vez; las capturas acumulativas de una cámara no se muestran como grabaciones diferentes. Los clips conservan su incursión de origen aunque la cámara los siga incluyendo después. Si hay varias grabaciones originales del mismo jugador, se distinguen como Grabación 1, Grabación 2… dentro de su lista, cada una con su secuencia e individuales. Todos los jugadores necesitan la versión 1.6.1 para preparar discos compartidos. El anfitrión puede preparar un disco dejando libre su ranura de disco. Cierra con Esc o con Cerrar. Esc no abre el menú de pausa por debajo del terminal.
La interfaz reutiliza en tiempo de ejecución la fuente Akzidenz, los fondos y el prefab de botón de los diálogos nativos: blanco sobre fondo oscuro y selección amarilla, con sus efectos y sonidos originales. Los assets pertenecen al juego y no se incluyen en el paquete. Tab, Mayús+Tab y Enter permiten recorrer y activar los controles. El terminal permanece separado de los menús de pausa y de los diálogos del juego para no solapar sus entradas.
- Cobrar visitas e ingresos pendientes: marcado al abrir y al seleccionar una grabación. La reproducción utiliza la evaluación y los importes originales del juego; solo concede las partes pendientes del pago de cuota y dinero.
- Permitir un cobro adicional con este disco: desmarcado. Autoriza expresamente un pago adicional al reproducir ese disco. Reintentar el mismo disco no vuelve a pagar. Preparar otro con esta opción autoriza otro cobro adicional. Se desactiva al quitar el primer check.
Los clips individuales, las selecciones de distintas incursiones y las secuencias de una misma grabación nativa comparten un pago original, aunque tengan más clips. Reproducir un clip primero puede consumir ese pago; la secuencia posterior no añade otro automáticamente. Se conserva el criterio por grabación original, sin repartir ni sumar nuevos pagos por cada clip. Esto evita cobrar otra vez al restaurar un disco roto o preparar una versión anterior. Si se quiere repetir un cobro, debe marcarse la segunda opción. Los recibos se sincronizan en las propiedades de la sala junto con los cambios nativos de dinero y cuota; los callbacks de otra campaña se rechazan. La migración entre anfitriones conserva los recibos recibidos por la sala, pero requiere validación en una partida conectada.
La preparación copia clips ya codificados, verifica sus bytes y registra un disco compatible con la reproducción y evaluación nativas. Espera confirmación de todos los clientes antes de entregarlo. No transmite vídeos por propiedades Photon ni inventa visitas o importes. Si faltan clips o eventos de evaluación en algún cliente, no entrega el disco y comunica el problema. No sustituye la codificación pendiente de la cámara ni recupera eventos nativos después de reiniciar el juego.
Los eventos y comentarios se copian y sus tiempos se ajustan a los clips seleccionados, conservando las puntuaciones y los buffers originales. Las duraciones nativas locales pueden tener pequeñas diferencias entre clientes; la precisión conectada requiere prueba manual. Un clip produce también fullRecording.webm. Para varios clips, se reutiliza el vídeo completo solo si hubo una extracción nativa exitosa que coincide exactamente con los clips de esa selección; de lo contrario, el disco reproduce sus clips y oculta la opción de guardar un único vídeo en el escritorio. No concatena ni recodifica automáticamente varios clips. El archivo permanente conserva los fullRecordings originales disponibles.
Las copias de reproducción temporales están en %TEMP%/CWRA_Terminal, separadas de Rec, Rec_RA y del archivo permanente. Se limpian al cambiar de campaña o salir, después de terminar las tareas pendientes. Al arrancar se recupera la limpieza de cachés propias abandonadas mediante marcadores y bloqueos. El catálogo es de esta visita a la sala, no un navegador de archivos históricos. Límites por sala: 32 discos, 128 clips por disco y 4096 clips en el catálogo. Si una grabación de una incursión supera 128 clips, conserva sus clips individuales y muestra un aviso; su secuencia completa no se ofrece en un solo disco. La comprobación conectada con varios jugadores y Virality sigue pendiente.
Controles de la tele
Durante la reproducción de una grabación de cámara, el anfitrión puede controlar la tele desde una distancia máxima de cuatro metros:
| Acción | Control |
|---|---|
| Pausar o reanudar | Ctrl+P |
| Terminar todo el disco, incluidos sus clips restantes | Ctrl+J |
| Terminar volviendo a usar la tele o su interacción de repetición | Interactuar |
| Repetir después de terminar | Interactuar con Repetir |
La pausa detiene el vídeo y el avance de su evaluación visual. Reanudar respeta la autorización nativa para ver el vídeo. Terminar ejecuta una sola vez el callback normal de finalización: concede el cobro pendiente según los checks del disco y habilita los controles finales. No borra ni recorta el vídeo. Repetir un vídeo ya terminado no crea otro pago. Cerrar la pantalla por cambio de estado cancela la reproducción sin anticipar su cobro.
Los comandos se envían ordenados mediante el PhotonView de la tele. Se rechazan emisores distintos del anfitrión, revisiones repetidas y comandos pertenecientes a otra reproducción. Todos necesitan Recording Archiver 1.3 para estos controles; si falta un cliente compatible, se conserva la interacción nativa. Los atajos de la tele no actúan mientras está abierto el terminal. Los discos de metraje perdido conservan su reproducción y repetición nativas. La sincronización en una sala conectada y la migración de anfitrión siguen pendientes de validación.
Dónde están los vídeos
Destino predeterminado: la carpeta Vídeos de Windows, subcarpeta ContentWarning. Generalmente %USERPROFILE%\Videos\ContentWarning, aunque Windows puede redirigir Vídeos.
ContentWarning/
20261101_M_<clave-partida>/
session_<id-partida>.json
I_001_<clave-incursión>/
R_<clave-vídeo>/
metadata.json
original/fullRecording.<ruta-hash>.<contenido-hash>.webm
segments/<dueño_o_Unknown>/<clave-clip>/output.<hashes>.webm
unknown/<archivo_con_hash>
I_002_<otra-clave>/
R_<clave-vídeo>/...
Una partida es una visita a una sala, detectada por InRoomState.Enter. Una campaña reiniciada tras fallar la cuota recibe otra partida. Salir y volver a entrar, incluso al mismo guardado, genera otra visita; SaveId se conserva cuando el cliente lo conoce para facilitar la correlación. No se presupone que todos los clientes conozcan el identificador del guardado.
Desde 1.1.1, las partidas nuevas usan YYYYMMDD_M_<clave> con la fecha local de inicio. Esa fecha queda fijada para todas sus incursiones, aunque la partida cruce medianoche. Las carpetas ya archivadas conservan sus nombres y rutas; no se trasladan automáticamente. Si una fuente antigua carece de fecha local y no tiene carpeta previa, se utiliza Undated_M_ en vez de inventar una fecha.
Cada carga subterránea efectiva crea una incursión. Volver a la superficie conserva la última incursión para la extracción posterior. I_000 corresponde a la superficie antes de la primera bajada observada. Los números son locales: si entras tarde, I_001 es tu primera bajada observada, aunque GameDay sea mayor. Los IDs completos, GameDay y el evento de procedencia están en Context dentro de metadata.json.
Un clip queda ligado a la incursión donde se observó y no cambia de incursión cuando llega su codificación o descarga más tarde. Los mismos GUID en otra partida/incursión generan registros diferentes. Un vídeo completo se guarda en el contexto de su extracción, pero puede combinar clips de varias incursiones: esa carpeta no afirma que todo su contenido pertenezca únicamente a esa bajada.
Los datos de 1.0 y las fuentes sin contexto demostrable conservan su organización anterior o quedan sin asignación, sin inventar partida. Se migra el índice a esquema 2 sin mover copias archivadas. No vuelvas a usar 1.0 sobre ese mismo destino. GroupBySession=false usa Matches_merged conservando separación de incursiones y claves únicas de grabación.
Las carpetas originales del juego representan vídeos y clips, no jugadores. Cada clip puede tener un portador, un codificador y un dueño asignado distintos. El mod registra cada identidad por separado. La agrupación por jugador utiliza solo el dueño demostrado mediante metadatos de ContentPOVs, si existen; las cámaras normales quedan en Unknown. No requiere ContentPOVs. El vídeo completo tiene una ubicación común porque puede incluir varios dueños. Los nombres de carpeta quedan estables; una identidad conocida más tarde se incorpora a metadata.json sin trasladar archivos anteriores. OwnerConflict señala dueños diferentes dentro del mismo vídeo.
Las claves de carpeta y los hashes de nombre se abrevian para reducir los problemas de rutas largas de Mono. metadata.json conserva los GUID y rutas originales y el SHA-256 completo; no se deduce el orden de las claves abreviadas.
Configuración
Tras el primer inicio: BepInEx/config/local.contentwarning.recordingarchiver.cfg, dentro del perfil. Cierra el juego para editarlo y reinicia después.
| Sección | Opción | Predeterminado |
|---|---|---|
| General | Enabled | true |
| General | OutputDirectory | Vídeos\ContentWarning |
| General | ArchiveFragments | true |
| General | ArchiveFullRecordings | true |
| Organization | GroupBySession | true |
| Organization | GroupByPlayer | true |
| Organization | UseSteamId | true |
| Processing | StabilitySeconds | 5 |
| Processing | SnapshotAfterSeconds | 120 |
| Processing | ScanIntervalSeconds | 2 |
| Logging | EnableDebugLogging | false |
| Terminal | Enabled | true |
| Shortcuts | OpenArchiveFolderShortcut | O + LeftControl |
| Shortcuts | OpenTerminalShortcut | U + LeftControl |
| Shortcuts | PauseTelevisionShortcut | P + LeftControl |
| Shortcuts | FinishTelevisionShortcut | J + LeftControl |
Los nombres de carpeta de jugadores se normalizan a Unicode NFC: se conservan tildes, ñ y letras de otros idiomas; emojis, símbolos, caracteres de control y componentes inválidos de Windows se sustituyen o eliminan. Se protegen los nombres reservados y los cortes de texto no parten parejas UTF-16. El sufijo de identidad distingue nombres que quedan iguales tras normalizar. El nombre original se conserva en pantalla y metadatos. Las carpetas ya archivadas se mantienen en su ubicación actual.
OutputDirectory acepta variables como %USERPROFILE% y debe ser absoluto, separado de Rec y de sus padres. UseSteamId=false sustituye el ID por una huella en los nombres de carpeta; los metadatos siguen conteniendo nombres e identificadores, porque son necesarios para asociar las grabaciones. No los publiques sin revisarlos. No se permiten junctions/enlaces simbólicos en las rutas recorridas. No hay OCR ni reconstrucción automáticos, por lo que no existen opciones que aparenten activarlos.
Copias y recuperación
Se espera un intervalo sin cambios de tamaño y fecha; después se abre la fuente excluyendo escritores y se copia por bloques. Se comprueba el tamaño y SHA-256 de la copia antes de publicarla. Cada contenido distinto tiene otra ruta. El archivo completo nunca se carga en memoria.
Un archivo que cambia continuamente puede recibir una instantánea cada 120 segundos. Su nombre contiene .snapshot y sus metadatos dicen incomplete-snapshot-media-unverified. Puede contener una mezcla temporal de bytes si el juego los reescribe mientras se captura. Nunca se considera un vídeo completo. Incluso byte-verified-media-unverified solo confirma los bytes copiados; no comprueba que un reproductor pueda abrirlos.
Los diarios .ra-*.partial.ra-journal permiten recuperar automáticamente una copia ya verificada tras un cierre abrupto, aunque la fuente haya desaparecido. Las operaciones sin verificar conservan .partial y su diario para recuperación manual. No se limpian ni se borran grabaciones automáticamente. Véase RECOVERY.md.
Protección antes de limpiar o sobrescribir Rec
Se protegen los puntos verificados de limpieza del menú y RecordingsHandler, el reemplazo de una carpeta de clip en RecordingPipe, la extracción de un solo clip, la combinación nativa y el guardado de un clip recibido. No se interceptan globalmente todas las operaciones de archivos ni se cambia el formato de red.
La fuente se traslada antes de la operación destructiva a una carpeta vecina de Rec: normalmente %TEMP%\Rec_RA\<id>\data, acompañada de retention.json con procedencia y contextos conocidos. Es un traslado en la misma unidad, no una copia grande en el hilo Unity. Así, el juego puede recrear Rec mientras el worker archiva lo retenido. Los traslados fallidos impiden el borrado o sustitución; una extracción puede devolver error y una recepción necesitar reintento. Si el juego cierra antes de finalizar la copia, lo retenido se recorre en el siguiente arranque.
Rec_RA no se limpia automáticamente, ni siquiera tras verificar el archivo persistente. Puede ocupar mucho espacio adicional. Limpia manualmente solo los lotes que hayas comprobado, con el juego cerrado y siguiendo RECOVERY.md. No desinstales y borres esa carpeta antes de revisar los pendientes.
Limitaciones y problemas
- La protección cubre las operaciones verificadas de esta build mientras el plugin está cargado. No recupera datos borrados antes de cargarlo ni cubre limpieza externa, otros mods que escriban directamente, actualizaciones con APIs distintas o pérdida física de la unidad.
- Si aparece
WITHOUT cleanup/overwrite protection, los hooks han fallado: solo queda archivado periódico. Revisa el diagnóstico del registro antes de confiar en la protección. Un fallo de retención por permisos, archivos abiertos o espacio insuficiente puede impedir que el juego complete la acción correspondiente; conserva la fuente para reintentar. - Solo se conservan archivos locales. No se garantiza tener los vídeos de todo el grupo. El archivado no transfiere vídeo; el terminal sincroniza definiciones y confirmaciones mediante propiedades de la sala.
- Un estado JSON corrupto, otra instancia con el mismo destino o un destino sin permisos pueden impedir arrancar el worker. El registro distingue la carga del plugin del arranque del worker. Usa otro destino o sigue RECOVERY.md; no borres el estado sin una copia de seguridad.
- Tras cinco errores consecutivos de copia se reintenta con una pausa de cinco minutos. Libera espacio o corrige permisos. Los originales permanecen intactos.
- Una ruta de destino demasiado larga puede fallar en algunos runtimes Windows. Usa una ruta corta, por ejemplo
D:\CW, si aparece PathTooLongException. - Las copias verificadas se reutilizan por ruta, tamaño y fecha de modificación. Se revisa su hash al reutilizarlas tras reiniciar. Modificar una fuente preservando exactamente tamaño y fecha puede eludir la detección de cambios.
- El impacto real en rendimiento, Virality, incorporación tardía, extracción y reproducción necesita pruebas dentro de una partida. Consulta TESTING.md.
Desinstalación: elimina el mod desde r2modman o retira su carpeta de plugins con el juego cerrado. Puedes retirar su configuración. Las grabaciones archivadas permanecen en el destino y nunca se eliminan al desinstalarlo.