您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
house script check
// ==UserScript== // @name house checker // @namespace https://shinoa.tech/ // @version 1.0 // @description house script check // @author christopher wayne love 30 // @match https://logs.shinoa.tech/tech/house // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; const checkedPlayers = {}; const style = document.createElement('style'); style.textContent = ` .house-checker-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.7); display: flex; justify-content: center; align-items: center; z-index: 9999; } .house-checker-content { background-color: #121212; padding: 20px; border-radius: 5px; max-width: 500px; width: 100%; color: white; } .house-checker-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .house-checker-close { cursor: pointer; font-size: 20px; } .house-checker-input-group { display: flex; margin-bottom: 15px; } .house-checker-input { flex: 1; padding: 8px; margin-right: 10px; background-color: #1E1E1E; border: 1px solid #333; color: white; border-radius: 3px; } .house-checker-button { background-color: #1976D2; color: white; border: none; padding: 8px 15px; border-radius: 3px; cursor: pointer; font-weight: bold; } .house-checker-button:hover { background-color: #1565C0; } .house-checker-button:disabled { background-color: #636363; cursor: not-allowed; } .house-checker-progress { margin-top: 15px; font-size: 14px; } .house-checker-results { max-height: 300px; overflow-y: auto; margin-top: 15px; border: 1px solid #333; padding: 10px; background-color: #1E1E1E; } .result-item { margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #333; } .banned { color: #F44336; } .not-banned { color: #4CAF50; } .cached { font-style: italic; } `; document.head.appendChild(style); function addCheckerButton() { const container = document.querySelector('div.row.justify-center'); if (!container) return; const checkerButton = document.createElement('button'); checkerButton.className = 'v-btn v-btn--has-bg theme--dark v-size--default house-checker-button'; checkerButton.style.height = '40px'; checkerButton.style.marginLeft = '10px'; checkerButton.style.marginBottom = '3px'; checkerButton.innerHTML = '<span class="v-btn__content">Чекер домов</span>'; checkerButton.addEventListener('click', showCheckerModal); container.appendChild(checkerButton); } function showCheckerModal() { const modal = document.createElement('div'); modal.className = 'house-checker-modal'; modal.innerHTML = ` <div class="house-checker-content"> <div class="house-checker-header"> <h3>Чекер домов</h3> <span class="house-checker-close">×</span> </div> <div class="house-checker-input-group"> <input type="number" class="house-checker-input" id="startId" placeholder="Начальный ID"> <input type="number" class="house-checker-input" id="endId" placeholder="Конечный ID"> <button class="house-checker-button" id="startCheck">Проверить</button> </div> <div class="house-checker-progress" id="progressInfo"></div> <div class="house-checker-results" id="results"></div> </div> `; document.body.appendChild(modal); document.querySelector('.house-checker-close').addEventListener('click', () => { document.body.removeChild(modal); }); document.getElementById('startCheck').addEventListener('click', function() { const startId = parseInt(document.getElementById('startId').value); const endId = parseInt(document.getElementById('endId').value); if (isNaN(startId) || isNaN(endId) || startId > endId) { alert('Пожалуйста, введите корректный диапазон ID'); return; } this.disabled = true; startHouseCheck(startId, endId).finally(() => { this.disabled = false; }); }); } async function startHouseCheck(startId, endId) { const progressInfo = document.getElementById('progressInfo'); const resultsContainer = document.getElementById('results'); resultsContainer.innerHTML = ''; const totalHouses = endId - startId + 1; let checked = 0; for (let id = startId; id <= endId; id++) { progressInfo.textContent = `Проверка: ${id} (${checked + 1}/${totalHouses})`; try { fillIdInput(id); await sleep(500); clickLoadButton(); await sleep(1500); const owner = getOwnerFromPage(); if (!owner || owner === '') { logResult(id, 'Нет владельца', false, resultsContainer, false); checked++; continue; } let isBanned; let isCached = false; if (owner in checkedPlayers) { isBanned = checkedPlayers[owner]; isCached = true; console.log(`Используем кешированные данные для ${owner}: ${isBanned ? 'заблокирован' : 'не заблокирован'}`); } else { isBanned = await checkPlayerBan(owner); checkedPlayers[owner] = isBanned; } logResult(id, owner, isBanned, resultsContainer, isCached); } catch (error) { console.error(`Ошибка при проверке дома ID ${id}:`, error); logResult(id, 'Ошибка: ' + error.message, false, resultsContainer, false); } checked++; await sleep(1000); } progressInfo.textContent = `Проверка завершена. Проверено ${checked} домов.`; } function fillIdInput(id) { const idInput = document.querySelector('input[type="text"]'); if (!idInput) { throw new Error('Поле для ввода ID не найдено'); } idInput.value = id; idInput.dispatchEvent(new Event('input', { bubbles: true })); idInput.dispatchEvent(new Event('change', { bubbles: true })); } function clickLoadButton() { let loadButton = document.querySelector('button[type="submut"]'); if (!loadButton) { loadButton = document.querySelector('button[type="submit"]'); } if (!loadButton) { const buttons = document.querySelectorAll('button'); for (const button of buttons) { const buttonText = button.textContent.toLowerCase(); if (buttonText.includes('загрузить') || buttonText.includes('поиск') || buttonText.includes('проверить') || buttonText.includes('найти')) { loadButton = button; break; } } if (!loadButton && buttons.length > 0) { loadButton = buttons[0]; } } if (!loadButton) { throw new Error('Кнопка загрузки информации не найдена'); } if (loadButton.disabled) { loadButton.disabled = false; } loadButton.click(); } function getOwnerFromPage() { const rows = document.querySelectorAll('tr'); let owner = null; for (const row of rows) { const cells = row.querySelectorAll('td'); if (cells.length >= 2) { const label = cells[0].textContent.trim(); if (label === 'Владелец') { owner = cells[1].textContent.trim(); break; } } } return owner; } async function checkPlayerBan(nickname) { const banCheckWindow = window.open('https://logs.shinoa.tech/tech/punish', '_blank'); const checkBanStatus = () => { return new Promise((resolve) => { const checkInterval = setInterval(() => { try { if (banCheckWindow.document.readyState === 'complete') { clearInterval(checkInterval); const nickInput = banCheckWindow.document.querySelector('input[type="text"]'); if (!nickInput) { banCheckWindow.close(); resolve(false); return; } nickInput.value = nickname; nickInput.dispatchEvent(new Event('input', { bubbles: true })); setTimeout(() => { let loadButton = banCheckWindow.document.querySelector('button[type="submit"]'); if (!loadButton) { loadButton = banCheckWindow.document.querySelector('button[type="submut"]'); } if (!loadButton) { const buttons = banCheckWindow.document.querySelectorAll('button'); for (const button of buttons) { const buttonText = button.textContent.toLowerCase(); if (buttonText.includes('проверить') || buttonText.includes('поиск') || buttonText.includes('загрузить') || buttonText.includes('найти')) { loadButton = button; break; } } if (!loadButton && buttons.length > 0) { loadButton = buttons[0]; } } if (loadButton) { if (loadButton.disabled) { loadButton.disabled = false; } loadButton.click(); setTimeout(() => { const banInfo = banCheckWindow.document.querySelector('div.v-card__title'); const isBanned = banInfo && banInfo.textContent.trim() === 'Блокировка'; banCheckWindow.close(); resolve(isBanned); }, 1500); } else { banCheckWindow.close(); resolve(false); } }, 500); } } catch (error) { clearInterval(checkInterval); console.error("Ошибка при проверке блокировки:", error); try { banCheckWindow.close(); } catch (e) {} resolve(false); } }, 500); setTimeout(() => { clearInterval(checkInterval); try { banCheckWindow.close(); } catch (e) {} resolve(false); }, 10000); }); }; return await checkBanStatus(); } function logResult(id, nickname, isBanned, container, isCached) { const statusClass = isBanned === true ? 'banned' : 'not-banned'; const statusText = isBanned === true ? 'заблокирован' : 'не заблокирован'; const cachedClass = isCached ? 'cached' : ''; const cachedText = isCached ? ' (кеш)' : ''; console.log(`ID: ${id}, Ник: ${nickname}, Статус: ${statusText}${cachedText}`); const resultItem = document.createElement('div'); resultItem.className = `result-item ${statusClass} ${cachedClass}`; resultItem.textContent = `ID: ${id}, Ник: ${nickname}, Статус: ${statusText}${cachedText}`; container.appendChild(resultItem); container.scrollTop = container.scrollHeight; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } window.addEventListener('load', addCheckerButton); if (document.readyState === 'complete') { addCheckerButton(); } })();