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();
}
})();