¿Ya tienes cuenta? Inicia sesión aquí
Últimos temas
-
Cómo funcionan las Mision...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
Ayer, 09:46 PM
» Respuestas: 0
» Vistas: 50 -
V6 Original/Dark/Memes (A...
Foro: Diseños Terminados
Último mensaje por: carlos007r
Ayer, 11:08 AM
» Respuestas: 26
» Vistas: 6,334 -
V5
Foro: Diseños Terminados
Último mensaje por: Aeikox
06-13-2026, 12:16 AM
» Respuestas: 8
» Vistas: 1,447 -
Risus 1.3 Actualizado jQu...
Foro: Risus 1.3
Último mensaje por: Tronlar
06-12-2026, 10:45 PM
» Respuestas: 55
» Vistas: 10,660 -
Preguntas Frecuentes y So...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-12-2026, 06:17 PM
» Respuestas: 0
» Vistas: 56 -
Cómo registrar tu comunid...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-12-2026, 05:32 PM
» Respuestas: 0
» Vistas: 50 -
Cómo monetizar tu comunid...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 07:19 PM
» Respuestas: 0
» Vistas: 48 -
Introducción al SEO para ...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 06:58 PM
» Respuestas: 0
» Vistas: 56 -
Guía completa de SEO para...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 06:48 PM
» Respuestas: 0
» Vistas: 58 -
Diccionario de términos b...
Foro: Guías y Tutoriales
Último mensaje por: Tronlar
06-11-2026, 01:41 PM
» Respuestas: 0
» Vistas: 82
Estadísticas del foro
- Mensajes del foro:1,957
- Temas del foro:614
- Miembros:1,036
- Último miembro:carlos007r
Captcha en Login v1.0
Mejora de seguridad para Risus Nova 2.0 — PHPost
Mejora de seguridad para Risus Nova 2.0 — PHPost
Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Añade el captcha de Cloudflare Turnstile al formulario de login, el mismo que ya tiene el registro. Evita ataques de fuerza bruta automatizados y bots que intenten acceder a cuentas.
🛡️ Características
- Usa el mismo Cloudflare Turnstile ya configurado en el registro
- Sin instalador ni base de datos
- Solo 2 cambios en 2 archivos
- Si no hay clave configurada el captcha se omite — no rompe nada
- Compatible con el mod de Protección de Login y 2FA
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- Cloudflare Turnstile configurado (clave pública y secreta en los ajustes del admin)
🛠️ Instalación
Paso 1 — Añadir el widget en head_menu.tpl
Abre themes/default/templates/sections/head_menu.tpl y busca:
Código:
<input type="submit" title="Entrar" value="Entrar" style="width:198px; margin-top:5px;" class="mBtn btnOk">Cámbialo por:
Código:
<div class="cf-turnstile" data-sitekey="{$tsConfig.pkey}" data-size="compact" style="margin:8px 0;"></div>
<input type="submit" title="Entrar" value="Entrar" style="width:198px; margin-top:5px;" class="mBtn btnOk">Paso 2 — Añadir el script de Turnstile en main_header.tpl
Abre themes/default/templates/sections/main_header.tpl y añade antes de </head>:
Código:
<script src="Registrate o inicia tu sesión para ver este contenido" async defer></script>Paso 3 — Verificar el captcha en ajax.login.php
Abre inc/php/ajax/ajax.login.php y busca:
Código:
if(empty($user) or empty($pass)) {
echo '0: Faltan datos';
} else {Cámbialo por:
Código:
if(empty($user) or empty($pass)) {
echo '0: Faltan datos';
} else {
// ── Verificar Turnstile ──
$captcha = $_POST['cf-turnstile-response'] ?? '';
if (!empty($tsCore->settings['pkey']) && !empty($tsCore->settings['skey'])) {
$opts = ['http' => ['method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query(['secret' => $tsCore->settings['skey'], 'response' => $captcha, 'remoteip' => $tsCore->getIP()])]];
$res = json_decode(@file_get_contents('Registrate o inicia tu sesión para ver este contenido false, stream_context_create($opts)), true);
if (empty($res['success'])) { echo '0: Verifica que no eres un robot.'; break; }
}
// ────────────────────────Paso 4 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
🗑️ Desinstalar
Restaura las líneas originales en head_menu.tpl y ajax.login.php.
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Doble Factor de Autenticación (2FA) v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Cada usuario puede activar el 2FA desde su cuenta. Al iniciar sesión, si las credenciales son correctas, se le pide un código de 6 dígitos enviado a su email antes de entrar.
🛡️ Características
- Código de 6 dígitos criptográficamente seguro
- Expira en 5 minutos
- Solo se puede usar una vez
- Máximo 3 intentos fallidos antes de invalidar
- Reenvío con límite de 60 segundos
- Cada usuario activa/desactiva desde su cuenta
- Email con diseño moderno
- Compatible con el mod de Protección de Login
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
- Correo mail() configurado en el servidor
🛠️ Instalación
Paso 1 — Ejecutar el instalador
Sube la carpeta install/ a la raíz y accede a:
Código:
Registrate o inicia tu sesión para ver este contenido⚠️ Elimina la carpeta install/ cuando termine.
Paso 2 — Subir los archivos
Código:
inc/class/c.2fa.php → inc/class/
inc/php/2fa.php → inc/php/
inc/php/ajax/ajax.2fa.php → inc/php/ajax/
themes/default/templates/t.2fa.tpl → themes/default/templates/Paso 3 — En ajax.login.php
Dentro del case 'login-user', donde se llama a loginUser, buscar:
Código PHP:
if(empty($user) or empty($pass)) echo '0: Faltan datos';
else echo $tsUser->loginUser($user, $pass, $reme);
Reemplazar por:
Código:
if(empty($user) or empty($pass)) {
echo '0: Faltan datos';
} else {
$resultado = $tsUser->loginUser($user, $pass, $reme);
if ($resultado === TRUE || is_numeric($resultado)) {
// ── 2FA ──
require_once TS_CLASS . 'c.2fa.php';
$ts2FA = new ts2FA();
if ($ts2FA->tieneActivo($tsUser->uid)) {
$tsUser->logoutUser($tsUser->uid, null);
$_SESSION['ts_2fa_pending'] = $tsUser->uid;
$_SESSION['ts_2fa_remember'] = $reme;
$ts2FA->enviarCodigo($tsUser->uid);
echo '3: ' . $tsCore->settings['url'] . '/2fa/';
break;
}
// ────────
echo $resultado;
} else {
echo $resultado;
}
}Paso 4 — En m.cuenta_cuenta.tpl
Buscar:
Código PHP:
<div class="buttons">
<input type="button" value="Guardar" onclick="cuenta.save(1)" class="mBtn btnOk">
<input type="button" value="Siguiente" onclick="cuenta.save(1, true)" class="mBtn btnOk">
</div>
Arriba agregar:
Código:
<div class="field">
<label>Verificación en dos pasos (2FA):</label>
<div style="padding:10px; background:#f8f9fa; border-radius:6px; border:1px solid #eee;">
<label style="display:flex; align-items:center; gap:10px; cursor:pointer;">
<input type="checkbox" name="2fa"
{if $tsUser->info.user_2fa}checked{/if}
onchange="cuenta.toggle2FA(this.checked)"/>
<span>
<strong>Activar 2FA</strong><br>
<small style="color:#888; font-weight:400;">Al iniciar sesión se te pedirá un código enviado a tu email.</small>
</span>
</label>
</div>
</div>Y en cuenta.js buscar:
Código PHP:
}
}
var avatar = {
Reemplazar por:
Código:
},
toggle2FA: function(activo) {
$.ajax({
type: 'POST',
url: global_data.url + '/2fa-toggle.php',
data: { activo: activo ? 1 : 0 },
dataType: 'json',
success: function(r) {
if (r.ok) {
cuenta.alert(1, activo ? '2FA activado' : '2FA desactivado', activo ? 'Ahora se pedirá un código al iniciar sesión.' : 'La verificación en dos pasos ha sido desactivada.');
}
}
});
}
}
var avatar = {Paso 5 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
🗑️ Desinstalar
Código:
ALTER TABLE u_miembros DROP COLUMN user_2fa;
DROP TABLE IF EXISTS w_2fa_tokens;Elimina los archivos y quita el hook de ajax.login.php.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Historial de Búsquedas v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Guarda las últimas 10 búsquedas del usuario en la sesión y las muestra debajo del campo de búsqueda como píldoras clicables para repetirlas con un clic.
🔍 Características
- Sin base de datos ni instalador
- Solo 2 archivos a sustituir
- Guarda hasta 10 búsquedas por sesión
- No guarda duplicados — si buscas lo mismo lo mueve al principio
- Clic en una búsqueda anterior la repite directamente
- Botón para borrar el historial con un clic
- Solo visible cuando hay historial guardado
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
🛠️ Instalación
Solo hay que sustituir 2 archivos:
Código:
inc/php/buscador.php → inc/php/
themes/default/templates/t.buscador.tpl → themes/default/templates/Borra la caché después de subir.
🗑️ Desinstalar
Restaura los archivos originales de buscador.php y t.buscador.tpl. No hay tablas que borrar.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Chat en Tiempo Real v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Sala de chat global en /chat/ con actualización automática cada 3 segundos. Solo usuarios registrados. Muestra los últimos 100 mensajes y la lista de usuarios conectados en tiempo real.
💬 Características
- Polling cada 3 segundos — funciona en cualquier hosting compartido
- Solo usuarios registrados pueden chatear
- Anti-flood — máximo 1 mensaje cada 2 segundos
- Mensajes guardados 24 horas y luego borrados automáticamente
- Lista de usuarios conectados en tiempo real
- Admins pueden borrar mensajes con un clic
- Máximo 500 caracteres por mensaje
- Compatible con el sistema de palabras prohibidas del script
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
- MySQL 5.7+ / MariaDB 10.4+
🛠️ Instalación
Paso 1 — Ejecutar el instalador
Sube la carpeta install/ a la raíz y accede a:
Código:
Registrate o inicia tu sesión para ver este contenido⚠️ Elimina la carpeta install/ cuando termine.
Paso 2 — Subir los archivos
Código:
inc/php/chat.php → inc/php/
inc/class/c.chat.php → inc/class/
inc/php/ajax/ajax.chat.php → inc/php/ajax/
themes/default/templates/t.chat.tpl → themes/default/templates/Paso 3 — En head_menu.tpl
Pon esto donde quieras:
Código:
<li class="tabbed {if $tsPage == 'chat'}here{/if}" id="tabbedchat">
<a href="{$tsConfig.url}/chat/">
<i class="fa-solid fa-comments"></i> Chat
</a>
</li>Paso 4 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
🗑️ Desinstalar
Código:
DROP TABLE IF EXISTS w_chat;
DROP TABLE IF EXISTS w_chat_presencia;Elimina los archivos y quita la ruta del .htaccess.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Tiempo de Lectura v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Muestra el tiempo estimado de lectura en la cabecera de cada post, justo debajo del título. Basado en una velocidad media de 200 palabras por minuto, igual que Medium o Dev.to.
⏱️ Características
- Sin base de datos ni instalador
- Solo 2 cambios en 2 archivos
- Calcula el tiempo en PHP — sin JavaScript
- Muestra mínimo 1 minuto
- Ignora el HTML del cuerpo — cuenta solo el texto
Ejemplos:
- Post de 400 palabras → 2 min de lectura
- Post de 50 palabras → 1 min de lectura
- Post de 1000 palabras → 5 min de lectura
🛠️ Instalación
Paso 1 — En posts.php
Buscar en inc/php/posts.php:
Código:
$smarty->assign("tsPost",$tsPost);Agregar debajo:
Código:
// ── Tiempo de lectura ──
$texto_plano = strip_tags(html_entity_decode($tsPost['post_body'], ENT_QUOTES, 'UTF-8'));
$palabras = str_word_count($texto_plano);
$minutos = max(1, (int)ceil($palabras / 200));
$smarty->assign('tsTiempoLectura', $minutos);
// ───────────────────────Paso 2 — Añadir en m.posts_content.tpl
Buscar:
Código:
<h1>{$tsPost.post_title}</h1>Añade justo después:
Código:
{if $tsTiempoLectura}
<div style="font-size:12px; color:#999; margin-top:4px; font-weight:400;">
<i class="fa-regular fa-clock"></i> {$tsTiempoLectura} min de lectura
</div>
{/if}O sube directamente el m.posts_content.tpl que dejo adjunto que ya incluye el cambio.
🗑️ Desinstalar
Quita las líneas añadidas en posts.php y el bloque del título en m.posts_content.tpl.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Sistema de Referidos v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Cada usuario tiene un enlace de invitación único. Cuando alguien se registra con ese enlace y activa su cuenta, el que invitó gana 10 puntos automáticamente y recibe una notificación.
🤝 Características
- Enlace de referido único por usuario: tudominio.com/registro?ref=NICK
- Puntos solo al activar la cuenta — evita cuentas falsas
- Un usuario solo puede tener un referidor
- Nadie puede referirse a sí mismo
- Notificación automática al ganar los puntos
- Widget en el perfil con enlace, estadísticas y lista de invitados
- Botón copiar enlace con un clic
- El ref se guarda en sesión — no se pierde si el usuario navega antes de registrarse
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
- MySQL 5.7+ / MariaDB 10.4+
🛠️ Instalación
Paso 1 — Ejecutar el instalador
Sube la carpeta install/ a la raíz y accede a:
Código:
Registrate o inicia tu sesión para ver este contenido⚠️ Elimina la carpeta install/ cuando termine.
Paso 2 — Subir los archivos
Código:
inc/class/c.referidos.php → inc/class/
themes/default/templates/modules/m.perfil_referidos.tpl → themes/default/templates/modules/Paso 3 — En c.registro.php
Buscar:
Código:
$tsData['user_id'] = db_exec('insert_id');Añade justo después:
Código:
// ── Referidos ──
require_once TS_CLASS . 'c.referidos.php';
$ref_nick = isset($_SESSION['ref_nick']) ? $_SESSION['ref_nick'] : ($tsCore->setSecure($_GET['ref'] ?? '') ?: $tsCore->setSecure($_POST['ref'] ?? ''));
if (!empty($ref_nick)) {
$tsRef = new tsReferidos();
$tsRef->guardarReferido($tsData['user_id'], $ref_nick);
}
// ────────────────Paso 4 — En c.user.php — userActivate()
Abre inc/class/c.user.php y busca dentro de userActivate() esta línea:
Código:
if(db_exec(array(__FILE__, __LINE__), 'query', 'UPDATE u_miembros SET user_activo = 1 WHERE user_id = \''.$tsUserID.'\'' )) {
return $tsData;Cambiar por:
Código:
if(db_exec(array(__FILE__, __LINE__), 'query', 'UPDATE u_miembros SET user_activo = 1 WHERE user_id = \''.$tsUserID.'\'' )) {
require_once TS_CLASS . 'c.referidos.php';
$tsRef = new tsReferidos();
$tsRef->procesarActivacion((int)$tsUserID);
return $tsData;Esto cubre tanto la activación por email como la activación directa sin email.
Paso 5 — Guardar ref en sesión (header.php)
Al final de header.php añade:
Código:
// ── Guardar ref en sesión ──
if (!empty($_GET['ref'])) {
$_SESSION['ref_nick'] = $tsCore->setSecure($_GET['ref']);
}
// ───────────────────────────Paso 6 — Widget en el perfil
En perfil.php buscar:
Código PHP:
$smarty->assign("tsGeneral",$tsGeneral);
Debajo agregar:
Código:
// ── Referidos ──
require_once TS_CLASS . 'c.referidos.php';
if ($tsUser->uid == $usuario['user_id']) {
$tsRef = new tsReferidos();
$ref_data = $tsRef->getReferidos($tsUser->uid);
$ref_data['url'] = tsReferidos::getUrl($tsUser->nick);
$ref_data['puntos_por_referido'] = tsReferidos::PUNTOS_POR_REFERIDO;
$smarty->assign('tsReferidos', $ref_data);
}
// ────────────────En m.perfil_sidebar.tpl añade donde quieras:
Código:
{include file='modules/m.perfil_referidos.tpl'}⚙️ Configurar puntos
Los puntos por referido se configuran en inc/class/c.referidos.php:
Código:
const PUNTOS_POR_REFERIDO = 10;🗑️ Desinstalar
Código:
DROP TABLE IF EXISTS u_referidos;Elimina los archivos y quita los hooks añadidos.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Reacciones en Posts v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Añade un sistema de reacciones con 6 emojis en cada post. Convive con el sistema de puntos existente — son completamente independientes. Un usuario puede dar puntos Y reaccionar al mismo post.
😊 Reacciones disponibles
- 👍 Me gusta
- ❤️ Me encanta
- 😂 Divertido
- 😮 Sorprendente
- 😢 Triste
- 😡 Enfadado
⚡ Características
- Un usuario solo puede tener una reacción por post
- Cambiar de reacción reemplaza la anterior automáticamente
- Pulsar la misma reacción la quita (toggle)
- Solo usuarios registrados pueden reaccionar
- Resumen visual con emojis y total de reacciones
- Actualización instantánea sin recargar la página
- Convive con el sistema de puntos — no lo reemplaza
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
- MySQL 5.7+ / MariaDB 10.4+
🛠️ Instalación
Paso 1 — Ejecutar el instalador
Sube la carpeta install/ a la raíz y accede a:
Código:
Registrate o inicia tu sesión para ver este contenidoPulsa Instalar ahora. Crea la tabla p_reacciones.
⚠️ Elimina la carpeta install/ cuando termine.
Paso 2 — Subir los archivos
Código:
inc/class/c.reacciones.php → inc/class/
inc/php/ajax/ajax.reacciones.php → inc/php/ajax/
themes/default/templates/modules/m.reacciones.tpl → themes/default/templates/modules/Paso 3 — En posts.php
Busca en inc/php/posts.php la línea:
Código:
$smarty->assign("tsPost",$tsPost);Añade justo después:
Código:
// ── Reacciones ──
require_once TS_CLASS . 'c.reacciones.php';
$tsReac = new tsReacciones();
$smarty->assign('tsReacciones', $tsReac->getReacciones($tsPost['post_id']));
// ────────────────Paso 4 — Añadir en m.posts_metadata.tpl
Busca el bloque de estadísticas que termina con </ul>:
Código PHP:
<div style="margin-top: 5px;">
<strong style="color: #333; font-size: 15px; display: block; line-height: 1;">{$tsPost.post_seguidores}</strong>
<span style="color: #999; font-size: 11px; text-transform: uppercase;">Seguidores</span>
</div>
</li>
</ul>
Debajo agregar:
Código:
{include file='modules/m.reacciones.tpl'}Paso 5 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
🗑️ Desinstalar
Código:
DROP TABLE IF EXISTS p_reacciones;Elimina los archivos subidos y quita los hooks añadidos.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Posts Programados v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
Permite a administradores y moderadores programar la publicación de posts en una fecha y hora concretas. El post se guarda como "programado" y se publica automáticamente cuando llega la hora, sin que nadie tenga que hacer nada.
🕐 Características
- Solo admins y moderadores pueden programar posts
- Mínimo 5 minutos en el futuro, máximo 1 año
- Publicación automática al cargar cualquier página
- Panel en el admin para ver todos los posts programados
- Publicar manualmente antes de la hora con un clic
- Cancelar devuelve el post a borradores
- Validación estricta de fechas — no se puede manipular desde el frontend
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
- MySQL 5.7+ / MariaDB 10.4+
🛠️ Instalación
Paso 1 — Ejecutar el instalador
Sube la carpeta install/ a la raíz y accede a:
Código:
Registrate o inicia tu sesión para ver este contenidoPulsa Instalar ahora. Añade la columna post_publish_at en la tabla p_posts.
⚠️ Elimina la carpeta install/ cuando termine.
Paso 2 — Subir los archivos
Código:
inc/class/c.scheduled.php → inc/class/
inc/php/ajax/ajax.scheduled.php → inc/php/ajax/
themes/default/templates/modules/m.scheduled_form.tpl → themes/default/templates/modules/
themes/default/templates/modules/m.scheduled_admin.tpl → themes/default/templates/admin_mods/Paso 3 — En c.posts.php
Busca el return $postID; al final de newPost() y añade justo antes:
Código:
// ── Posts programados ──
if (!empty($_POST['post_publish_at']) && $tsUser->is_admod) {
require_once TS_CLASS . 'c.scheduled.php';
$tsSched = new tsScheduled();
$ts = tsScheduled::parseFecha($_POST['post_publish_at']);
if ($ts > 0) {
$tsSched->programar($postID, $ts);
}
}
// ────────────────────────Paso 4 — En header.php
Abre header.php de la raíz y añade al final, antes del cierre:
Código:
// ── Publicar posts programados ──
require_once TS_CLASS . 'c.scheduled.php';
(new tsScheduled())->publicarPendientes();
// ────────────────────────────────Paso 5 — En m.agregar.form.tpl
Buscar:
{if ($tsUser->is_admod > 0 || $tsUser->permisos.moedpo) && $tsDraft.b_title && $tsDraft.b_user != $tsUser->uid}
Arriba agregar:
Código:
{include file='modules/m.scheduled_form.tpl'}Paso 6 — Panel en el admin
En admin.php añade antes de :
Código PHP:
} elseif($action == 'feed'){
Agregar:
Código:
} elseif($action == 'scheduled'){
require_once TS_CLASS . 'c.scheduled.php';
$tsSched = new tsScheduled();
$smarty->assign('tsProgramados', $tsSched->getProgramados());En t.admin.tpl añade antes del {/if} final:
Código:
{elseif $tsAction == 'scheduled'}
{include file='admin_mods/m.scheduled_admin.tpl'}En m.admin_sidemenu.tpl añade donde prefieras:
Código:
<li id="a_scheduled">
<a href="{$tsConfig.url}/admin/scheduled">
<span class="nav-icon">🕐</span> Posts Programados
</a>
</li>Paso 7 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
🗑️ Desinstalar
Código:
ALTER TABLE p_posts DROP COLUMN post_publish_at;Elimina los archivos subidos y quita los hooks añadidos.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Protección de Login v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Protección contra ataques de fuerza bruta en el login. Bloquea automáticamente por IP y por nick tras demasiados intentos fallidos, con bloqueo progresivo y log completo de accesos visible desde el panel de admin.
Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
[img]Registrate o inicia tu sesión para ver este contenido[/img]
🛡️ Características
- Doble bloqueo — por IP y por nombre de usuario de forma independiente
- Bloqueo progresivo — 1er bloqueo 15 min, 2do 1 hora, 3er bloqueo y siguientes 24 horas
- 5 intentos antes de bloquear (configurable en el código)
- Admin nunca se bloquea
- Login correcto resetea los contadores
- Log completo — fecha, IP, nick y resultado de cada intento (guardado 7 días)
- Panel en el admin — ver intentos y desbloquear manualmente con un clic
- Aviso al usuario — muestra cuántos intentos le quedan antes del bloqueo
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
- MySQL 5.7+ / MariaDB 10.4+
🛠️ Instalación
Paso 1 — Ejecutar el instalador
Sube la carpeta install/ a la raíz del sitio y accede a:
Código:
Registrate o inicia tu sesión para ver este contenidoPulsa Instalar ahora. El instalador creará:
- w_login_log — registro de todos los intentos de login
- w_login_bloqueos — bloqueos activos por IP y nick
⚠️ Elimina la carpeta install/ del servidor cuando termine.
Paso 2 — Subir los archivos
Código:
inc/class/c.loginlog.php → inc/class/
inc/php/ajax/ajax.loginlog.php → inc/php/ajax/
themes/default/css/loginlog.css → themes/default/css/
themes/default/templates/modules/
m.loginlog_admin.tpl → themes/default/templates/modules/Paso 3 — En ajax.login.php
Abre inc/php/ajax/ajax.login.php y reemplaza el case 'login-user' completo por:
Código:
case 'login-user':
//<---
$user = $tsCore->setSecure($_POST['nick']);
$pass = $tsCore->setSecure($_POST['pass']);
$reme = (($_POST['rem'] ?? '') == 'true') ? true : false;
//
if(empty($user) or empty($pass)) echo '0: Faltan datos';
else echo $tsUser->loginUser($user, $pass, $reme);
//--->
break;Cambiar por:
Código:
case 'login-user':
//<---
$user = $tsCore->setSecure($_POST['nick']);
$pass = $tsCore->setSecure($_POST['pass']);
$reme = (($_POST['rem'] ?? '') == 'true') ? true : false;
$ip = $tsCore->getIP();
if (empty($user) || empty($pass)) {
echo '0: Faltan datos';
break;
}
// ── Protección login ──
require_once TS_CLASS . 'c.loginlog.php';
$tsLL = new tsLoginLog();
$bloqueo = $tsLL->estaBloqueado($user, $ip);
if ($bloqueo) {
$tiempo = $tsLL->formatearTiempo($bloqueo['faltan']);
echo '0: Demasiados intentos fallidos. Inténtalo de nuevo en ' . $tiempo . '.';
break;
}
$resultado = $tsUser->loginUser($user, $pass, $reme);
if ($resultado === TRUE || is_numeric($resultado)) {
$tsLL->registrar($user, $ip, true);
$tsLL->resetear($user, $ip);
echo $resultado;
} else {
$tsLL->registrar($user, $ip, false);
$info = $tsLL->procesarFallo($user, $ip);
$restantes = $info['restantes'];
if ($restantes > 0) {
echo $resultado . ' (' . $restantes . ' intento' . ($restantes != 1 ? 's' : '') . ' restante' . ($restantes != 1 ? 's' : '') . ')';
} else {
echo '0: Cuenta bloqueada temporalmente por seguridad.';
}
}
// ────────────────────
//--->
break;Paso 4 — Panel en el admin (opcional)
Para ver el log desde el panel de admin añade en la plantilla t.admin.pl arriba de:
Código:
{/if}Código:
{elseif $tsAction == 'loginlog'}
{include file='admin_mods/m.loginlog_admin.tpl'}En admin.php buscar:
Código PHP:
} elseif($action == 'feed'){
Agregar antes:
Código:
} elseif($action == 'loginlog'){
require_once TS_CLASS . 'c.loginlog.php';
$tsLL = new tsLoginLog();
$smarty->assign('tsLoginLog', $tsLL->getLog());
$smarty->assign('tsBloqueos', $tsLL->getBloqueos());En m.admin_sidemenu.tpl buscar:
Código PHP:
<h4>Usuarios</h4>
<ul class="admin-nav-list">
<li id="a_users"><a href="{$tsConfig.url}/admin/users"><span class="nav-icon">👤</span> Usuarios</a></li>
<li id="a_sesiones"><a href="{$tsConfig.url}/admin/sesiones"><span class="nav-icon">🔑</span> Sesiones</a></li>
<li id="a_nicks"><a href="{$tsConfig.url}/admin/nicks"><span class="nav-icon">🆔</span> Nicks</a></li>
<li id="a_rangos"><a href="{$tsConfig.url}/admin/rangos"><span class="nav-icon">💎</span> Rangos</a></li>
</ul>
Debajo agregar:
Código PHP:
<h4>Seguridad</h4>
<ul class="admin-nav-list">
<li id="a_loginlog"><a href="{$tsConfig.url}/admin/loginlog"><span class="nav-icon">🛡️</span> Protección Login</a></li>
</ul>
Paso 5 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
🗑️ Desinstalar
Código:
DROP TABLE IF EXISTS w_login_log;
DROP TABLE IF EXISTS w_login_bloqueos;Elimina los archivos subidos y restaura el case 'login-user' original en ajax.login.php.
Descarga
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par... contenido
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Vídeos y Medios Embebidos v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost
Nuevo módulo para Risus Nova 2.0 — PHPost
Con este mod basta con pegar una URL en el cuerpo de un post para que se convierta automáticamente en el player embebido correspondiente. Sin etiquetas especiales, sin código — solo la URL en una línea.
▶ Captura
[img]Registrate o inicia tu sesión para ver este contenido[/img]
▶ Plataformas soportadas
- YouTube — youtube.com/watch?v=ID, youtu.be/ID y /shorts/ID
- Vimeo — vimeo.com/ID
- Twitter / X — tweets embebidos con el widget oficial
- Spotify — canciones, álbumes, playlists, podcasts y episodios
- TikTok — vídeos embebidos con el widget oficial
✨ Características
- Sin instalador — no crea tablas ni modifica la base de datos
- Detección automática de la plataforma por la URL
- Player responsive adaptado a móvil
- Carga lazy para no ralentizar la página
- No modifica los datos guardados en BD, solo el renderizado
- Spotify adapta la altura según el tipo (track/podcast = compacto, álbum/playlist = expandido)
🔒 Seguridad
Cada URL pasa por una cadena de validaciones antes de generar el embed:
- IDs estrictamente validados — YouTube acepta solo exactamente 11 caracteres alfanuméricos. Vimeo solo dígitos. Twitter, TikTok y Spotify tienen sus propios rangos y patrones
- Lista blanca de tipos en Spotify — solo se permiten track, album, playlist, episode y show. Cualquier otro valor se ignora
- Sandbox en iframes — todos los iframes tienen el atributo sandbox con los permisos mínimos necesarios para funcionar
- youtube-nocookie.com — YouTube se carga desde el dominio de privacidad mejorada para no rastrear a los usuarios
- Vimeo con ?dnt=1 — Do Not Track activado
- URLs reconstruidas — nunca se usa la URL original del usuario directamente en el src del iframe. Se construye una URL nueva y limpia con el ID validado
- Si el ID no pasa la validación — se deja la URL original sin tocar en lugar de romper el post
📋 Requisitos
- Risus Nova 2.0 instalado y funcionando
- PHP 8.0+
🛠️ Instalación
Paso 1 — Subir los archivos
Código:
inc/class/c.embed.php → inc/class/
themes/default/css/embed.css → themes/default/css/Paso 2 — En c.posts.php
Abre inc/class/c.posts.php y busca dentro de getPost() este bloque:
Código:
$postData['post_body'] = preg_replace(
'/<oembed url="https:\/\/www\.youtube\.com\/watch\?v=([^"]+)"><\/oembed>/s',
'<iframe width="560" height="315" src="Registrate o inicia tu sesión para ver este contenido" frameborder="0" allowfullscreen></iframe>',
$postData['post_body']
);Justo después añade:
Código:
// ── Embeds automáticos ──
require_once TS_CLASS . 'c.embed.php';
$tsEmbed = new tsEmbed();
$postData['post_body'] = $tsEmbed->process($postData['post_body']);
// ────────────────────────Paso 3 — Borrar la caché
Borra el contenido de la carpeta /cache/ del sitio.
📝 Uso
Al crear un post pega la URL en el cuerpo en una línea aparte:
Código:
Mira este vídeo:
Registrate o inicia tu sesión para ver este contenido
Y esta canción:
Registrate o inicia tu sesión para ver este contenidoEl mod la detecta y la convierte automáticamente en el player al mostrar el post.
🗑️ Desinstalar
- Elimina inc/class/c.embed.php
- Elimina themes/default/css/embed.css
- Quita el hook añadido en c.posts.php
- Borra la caché
Descarga
Mediafire
http://Registrate o inicia tu sesión par...0.rar/file
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.
Mediafire
http://Registrate o inicia tu sesión par...0.rar/file
Google Drive
http://Registrate o inicia tu sesión par... contenido
¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.

