// ==UserScript==
// @name CSTAT Orientation Timer Bypass
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Bypass timer restrictions on Texas A&M CSTAT Online Orientation pages
// @author Bean0-0
// @license MIT
// @match https://cstat-onlineorientation.tamu.edu/*
// @match *://cstat-onlineorientation.tamu.edu/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
console.log('CSTAT Orientation Timer Bypass loaded');
// Override setTimeout and setInterval to bypass timers
const originalSetTimeout = window.setTimeout;
const originalSetInterval = window.setInterval;
// Override setTimeout to intercept timer-based delays
window.setTimeout = function(callback, delay, ...args) {
// Only bypass very long delays (likely orientation timers), keep shorter ones intact
if (delay > 30000) { // Only affect delays longer than 30 seconds
console.log(`Bypassing setTimeout delay: ${delay}ms -> 1000ms`);
delay = 1000;
}
const id = originalSetTimeout.call(this, callback, delay, ...args);
return id;
};
// Override setInterval to intercept repeating timers
window.setInterval = function(callback, delay, ...args) {
// Only affect very long intervals, leave normal ones alone
if (delay > 30000) {
console.log(`Bypassing setInterval delay: ${delay}ms -> 5000ms`);
delay = 5000;
}
const id = originalSetInterval.call(this, callback, delay, ...args);
return id;
};
// Function to force enable navigation elements
function enableNavigation() {
// Look for disabled navigation elements and enable them
const disabledElements = document.querySelectorAll('[disabled], .disabled, [aria-disabled="true"]');
disabledElements.forEach(element => {
element.removeAttribute('disabled');
element.classList.remove('disabled');
element.setAttribute('aria-disabled', 'false');
element.style.pointerEvents = 'auto';
element.style.opacity = '1';
});
// Look for next/continue buttons and enable them
const nextButtons = document.querySelectorAll('button[class*="next"], button[class*="continue"], a[class*="next"], a[class*="continue"], .next-button, .continue-button, [data-action*="next"], [data-action*="continue"]');
nextButtons.forEach(button => {
button.removeAttribute('disabled');
button.classList.remove('disabled');
button.style.pointerEvents = 'auto';
button.style.opacity = '1';
button.style.cursor = 'pointer';
});
// Look for locked content and unlock it
const lockedElements = document.querySelectorAll('.locked, [class*="locked"], [data-locked="true"]');
lockedElements.forEach(element => {
element.classList.remove('locked');
element.removeAttribute('data-locked');
element.style.pointerEvents = 'auto';
element.style.opacity = '1';
});
}
// Function to override common timer-related variables
function overrideTimerVariables() {
// Common timer variables that might be used
if (window.FEATURE_SETTINGS) {
window.FEATURE_SETTINGS.showTimedReleaseTopics = false;
console.log('Disabled timed release topics');
}
// Try to find and override timer-related configurations
if (window.orientationConfig) {
window.orientationConfig.timer = false;
window.orientationConfig.timedRelease = false;
}
// Override video player timers if present
if (window.kalturaPlayer) {
try {
window.kalturaPlayer.duration = 0.1;
} catch (e) {
console.log('Could not override Kaltura player duration');
}
}
}
// Function to simulate video completion
function simulateVideoCompletion() {
// Dispatch video end events
const videos = document.querySelectorAll('video');
videos.forEach(video => {
if (video.duration && video.currentTime < video.duration) {
video.currentTime = video.duration;
video.dispatchEvent(new Event('ended'));
video.dispatchEvent(new Event('timeupdate'));
console.log('Simulated video completion');
}
});
// Try to trigger Kaltura player events
if (window.kalturaPlayer) {
try {
window.kalturaPlayer.dispatchEvent('ended');
window.kalturaPlayer.dispatchEvent('timeupdate');
} catch (e) {
console.log('Could not dispatch Kaltura events');
}
}
}
// Function to add bypass controls to the page
function addBypassControls() {
if (document.getElementById('timer-bypass-controls')) return;
const controlPanel = document.createElement('div');
controlPanel.id = 'timer-bypass-controls';
controlPanel.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
background: #a61830;
color: white;
padding: 10px;
border-radius: 5px;
z-index: 999999;
font-family: Arial, sans-serif;
font-size: 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
`;
controlPanel.innerHTML = `
<div style="margin-bottom: 10px; font-weight: bold;">Timer Bypass Controls</div>
<button id="enable-nav-btn" style="margin: 2px; padding: 5px; background: #fff; color: #a61830; border: none; border-radius: 3px; cursor: pointer;">Enable Navigation</button><br>
<button id="complete-video-btn" style="margin: 2px; padding: 5px; background: #fff; color: #a61830; border: none; border-radius: 3px; cursor: pointer;">Complete Videos</button><br>
<button id="skip-timers-btn" style="margin: 2px; padding: 5px; background: #fff; color: #a61830; border: none; border-radius: 3px; cursor: pointer;">Skip All Timers</button><br>
<button id="toggle-bypass-btn" style="margin: 2px; padding: 5px; background: #fff; color: #a61830; border: none; border-radius: 3px; cursor: pointer;">Toggle Auto-Bypass</button>
<div id="bypass-status" style="margin-top: 5px; font-size: 10px;">Auto-Bypass: ON</div>
`;
document.body.appendChild(controlPanel);
// Add event listeners with better functionality
let autoBypassEnabled = true;
document.getElementById('enable-nav-btn').addEventListener('click', enableNavigation);
document.getElementById('complete-video-btn').addEventListener('click', simulateVideoCompletion);
document.getElementById('skip-timers-btn').addEventListener('click', () => {
// Force skip any visible timers or waiting periods
const waitingElements = document.querySelectorAll('[class*="wait"], [class*="timer"], [class*="countdown"]');
waitingElements.forEach(el => el.style.display = 'none');
// Try to click any "skip" or "continue" buttons
const skipButtons = document.querySelectorAll('button[class*="skip"], a[class*="skip"], [data-action*="skip"]');
skipButtons.forEach(btn => btn.click());
enableNavigation();
simulateVideoCompletion();
console.log('Attempted to skip all timers');
});
document.getElementById('toggle-bypass-btn').addEventListener('click', () => {
autoBypassEnabled = !autoBypassEnabled;
document.getElementById('bypass-status').textContent = `Auto-Bypass: ${autoBypassEnabled ? 'ON' : 'OFF'}`;
console.log(`Auto-bypass ${autoBypassEnabled ? 'enabled' : 'disabled'}`);
});
}
// Function to handle page mutations and continuously bypass restrictions
function setupMutationObserver() {
const observer = new MutationObserver((mutations) => {
// Throttle the mutation handling to prevent performance issues
clearTimeout(window.mutationTimeout);
window.mutationTimeout = setTimeout(() => {
enableNavigation();
}, 500); // Wait 500ms before processing changes
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['disabled', 'class', 'aria-disabled']
});
}
// Initialize when DOM is ready
function initialize() {
overrideTimerVariables();
enableNavigation();
addBypassControls();
setupMutationObserver();
// Much less aggressive periodic check - only every 10 seconds
setInterval(() => {
enableNavigation();
}, 10000);
console.log('Timer bypass initialized');
}
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialize);
} else {
initialize();
}
// Also try to initialize immediately for early interception
setTimeout(initialize, 100);
})();