您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Ограничь свое время на DTF. Userscript version. Автор: Dude
- // ==UserScript==
- // @name antiDTF (Userscript)
- // @namespace http://tampermonkey.net/
- // @version 1.1
- // @description Ограничь свое время на DTF. Userscript version. Автор: Dude
- // @author Dude (converted)
- // @match *://dtf.ru/*
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_addStyle
- // @grant GM_registerMenuCommand
- // @run-at document-idle
- // @license MIT
- // ==/UserScript==
- (async function() {
- 'use strict';
- // --- Configuration Keys ---
- const KEY_DAILY_LIMIT = 'antiDTF_dailyLimit';
- const KEY_START_TIMESTAMP = 'antiDTF_startTimestamp';
- const KEY_LAST_RESET = 'antiDTF_lastReset';
- // --- Helper Functions for Storage ---
- async function getConfig(key, defaultValue = null) {
- return await GM_getValue(key, defaultValue);
- }
- async function setConfig(key, value) {
- await GM_setValue(key, value);
- }
- // --- Blocked Page Styling and Content ---
- const blockedStyles = `
- body {
- background: #ff00ff !important;
- color: #ffff00 !important;
- font-family: 'Comic Sans MS', cursive, sans-serif !important;
- text-align: center !important;
- font-size: 32px !important;
- margin: 0 !important;
- padding: 0 !important;
- height: 100vh !important;
- display: flex !important;
- align-items: center !important;
- justify-content: center !important;
- overflow: hidden !important;
- }
- /* Hide everything else just in case */
- body > *:not(#antiDTF-blocked-message) {
- display: none !important;
- }
- `;
- const blockedHTML = `<div id="antiDTF-blocked-message">Лимит DTF на сегодня исчерпан. Пиздуй работать.</div>`;
- // --- Core Time Limit Check Logic ---
- async function checkTimeLimit() {
- const dailyLimit = await getConfig(KEY_DAILY_LIMIT);
- let startTimestamp = await getConfig(KEY_START_TIMESTAMP);
- let lastReset = await getConfig(KEY_LAST_RESET);
- // If limit is not set or invalid, do nothing
- if (dailyLimit === null || isNaN(dailyLimit) || dailyLimit <= 0) {
- console.log("antiDTF: Limit not set or invalid.");
- return false; // Not blocked
- }
- const limitMinutes = parseInt(dailyLimit, 10);
- const nowDate = new Date().toDateString();
- // Check if it's a new day
- if (lastReset !== nowDate) {
- console.log("antiDTF: New day detected. Resetting timer.");
- startTimestamp = Date.now();
- await setConfig(KEY_LAST_RESET, nowDate);
- await setConfig(KEY_START_TIMESTAMP, startTimestamp);
- console.log(`antiDTF: Timer reset. Limit: ${limitMinutes} minutes.`);
- return false; // Not blocked yet today
- }
- // Check if startTimestamp is valid (necessary after first setting the limit)
- if (!startTimestamp) {
- console.log("antiDTF: Start timestamp missing for today. Initializing.");
- startTimestamp = Date.now();
- await setConfig(KEY_START_TIMESTAMP, startTimestamp);
- return false; // Not blocked yet
- }
- // Calculate elapsed time
- const elapsedMs = Date.now() - startTimestamp;
- const elapsedMinutes = Math.floor(elapsedMs / 60000);
- console.log(`antiDTF: Time check - Elapsed: ${elapsedMinutes} min / Limit: ${limitMinutes} min`);
- // Check if limit is exceeded
- if (elapsedMinutes >= limitMinutes) {
- console.log("antiDTF: Daily limit exceeded. Blocking page.");
- blockPage();
- return true; // Blocked
- }
- return false; // Not blocked
- }
- // --- Function to Block the Page ---
- function blockPage() {
- // Stop further loading/scripts if possible
- try { window.stop(); } catch (e) { console.warn("antiDTF: Could not stop window loading.", e); }
- // Apply styles first
- GM_addStyle(blockedStyles);
- // Replace body content
- document.body.innerHTML = blockedHTML;
- // Set title
- document.title = "antiDTF - Лимит исчерпан";
- }
- // --- Settings via Menu Commands (Replaces Popup) ---
- // 1. Set/Change Limit
- GM_registerMenuCommand("antiDTF: Установить/Изменить лимит", async () => {
- const currentLimit = await getConfig(KEY_DAILY_LIMIT, '');
- const newLimitStr = prompt(`Введите дневной лимит времени на DTF в минутах.\n(Текущий: ${currentLimit || 'не установлен'})\nВведите 0 или оставьте пустым для снятия лимита.`, currentLimit);
- if (newLimitStr === null) return; // User cancelled
- const newLimit = parseInt(newLimitStr.trim(), 10);
- if (!isNaN(newLimit) && newLimit > 0) {
- await setConfig(KEY_DAILY_LIMIT, newLimit);
- // Reset timer immediately when limit is set/changed
- const today = new Date().toDateString();
- await setConfig(KEY_LAST_RESET, today);
- await setConfig(KEY_START_TIMESTAMP, Date.now());
- alert(`antiDTF: Лимит установлен на ${newLimit} минут в день.\nТаймер сброшен на сегодня.`);
- // Reload to apply immediately (especially important if currently blocked)
- location.reload();
- } else if (newLimitStr.trim() === '' || newLimit === 0) {
- await setConfig(KEY_DAILY_LIMIT, null); // Use null to indicate no limit
- await setConfig(KEY_START_TIMESTAMP, null);
- await setConfig(KEY_LAST_RESET, '');
- alert("antiDTF: Лимит снят.");
- // Reload to unblock if currently blocked
- location.reload();
- } else {
- alert("antiDTF: Ошибка. Введите положительное число минут или 0 для снятия лимита.");
- }
- });
- // 2. Extend Limit ("Продлить как лох")
- GM_registerMenuCommand("antiDTF: Продлить как лох", async () => {
- const currentLimit = await getConfig(KEY_DAILY_LIMIT);
- if (currentLimit === null) {
- alert("antiDTF: Сначала установите основной лимит.");
- return;
- }
- const addMinutesStr = prompt(`На сколько минут продлить сегодняшний лимит? (Текущий: ${currentLimit} минут)`);
- if (addMinutesStr === null) return; // User cancelled
- const addMinutes = parseInt(addMinutesStr.trim(), 10);
- if (!isNaN(addMinutes) && addMinutes > 0) {
- const newLimit = (parseInt(currentLimit, 10) || 0) + addMinutes;
- await setConfig(KEY_DAILY_LIMIT, newLimit);
- alert(`antiDTF: Лимит продлен на ${addMinutes} минут.\nНовый лимит на сегодня: ${newLimit} минут.\nСтраница будет перезагружена.`);
- // Don't reset startTimestamp here, just increase the ceiling for today
- location.reload(); // Reload to potentially unblock or continue browsing
- } else {
- alert("antiDTF: Ошибка. Введите положительное число минут.");
- }
- });
- // 3. Check Status
- GM_registerMenuCommand("antiDTF: Проверить статус", async () => {
- const dailyLimit = await getConfig(KEY_DAILY_LIMIT);
- let startTimestamp = await getConfig(KEY_START_TIMESTAMP);
- let lastReset = await getConfig(KEY_LAST_RESET);
- if (dailyLimit === null) {
- alert("antiDTF: Лимит времени не установлен.");
- return;
- }
- const limitMinutes = parseInt(dailyLimit, 10);
- const nowDate = new Date().toDateString();
- if (lastReset !== nowDate || !startTimestamp) {
- // Handles both new day and cases where start timestamp wasn't set yet
- alert(`antiDTF:\nЛимит: ${limitMinutes} минут в день.\nТаймер на сегодня еще не запущен (начнет отсчет при следующем взаимодействии с сайтом).`);
- return;
- }
- const elapsedMs = Date.now() - startTimestamp;
- const elapsedMinutes = Math.floor(elapsedMs / 60000);
- const remainingMinutes = Math.max(0, limitMinutes - elapsedMinutes);
- const remainingSecondsTotal = Math.max(0, (limitMinutes * 60) - Math.floor(elapsedMs / 1000));
- const remainingSecs = remainingSecondsTotal % 60;
- const remainingMins = Math.floor(remainingSecondsTotal / 60);
- alert(`antiDTF Статус:\nЛимит: ${limitMinutes} минут.\nИспользовано сегодня: ${elapsedMinutes} минут.\nОсталось: ${remainingMins} мин ${remainingSecs < 10 ? '0' : ''}${remainingSecs} сек.`);
- });
- // --- Initial Execution ---
- console.log("antiDTF Userscript running on:", window.location.href);
- // Run the check when the script loads
- await checkTimeLimit();
- // Note: The script runs on 'document-idle', so the page content might already be visible
- // for a moment before being blocked if the limit is exceeded. The check runs on every
- // matching page load/navigation.
- })();