NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Kittypet // @namespace Sirotkin1 // @version 0.1 // @description Иногда я задаюсь вопросом, зачем я это делаю // @author Сирота [1390991] // @copyright Wilhelm Birkner [https://vk.com/washclown] // @updateURL https://openuserjs.org/meta/Sirotkin1/Kittypet.meta.js // @downloadURL https://openuserjs.org/install/Sirotkin1/Kittypet.user.js // @match *://catwar.net/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; let fillButtonClickCount = 0; // **Объявляем счетчик вне обработчика** const userIdPageUrl = 'https://catwar.net'; function getUserIdFromPage() { return fetch(userIdPageUrl) .then(response => response.text()) .then(html => { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const userIdElement = doc.querySelector('#id_val'); if (userIdElement) { return userIdElement.textContent; } else { console.error('Не удалось найти ID пользователя на странице.'); return null; } }) .catch(error => { console.error('Ошибка при получении страницы с ID:', error); return null; }); } // Стили для элементов шаблона const style = document.createElement('style'); style.innerHTML = ` .template-field { margin-top: 10px; display: flex; align-items: center; flex-wrap: wrap; font-size: 13px; font-family: Arial, sans-serif; } .template-field input, .template-field select { margin: 0 5px; padding: 3px 5px; border: 1px solid #ccc; border-radius: 0px; font-size: 13px; max-width: 95px; } #templateSelect { margin-top: 5px; margin-bottom: 5px; font-size: 13px; } #dateOffset { width: 50px; font-size: 13px; } `; document.head.appendChild(style); // Шаблоны для разных блогов const templates = { // Руферы 'blog696447': [{ name: 'Передача предмета', template: 'Я, [[n]l[/n]ink{id}], передал(а) дому [{count}] предмет [{item_select}], [{points}], [url={screenshot}]Скриншот из истории[/url].' }, { name: 'Очередь на перо', template: 'Я, [[n]l[/n]ink{id}], хочу встать в очередь на получение ({color_select}), {date}.' }, { name: 'Выкуп перьев', template: 'Я, [[n]l[/n]ink{id}], хочу выкупить ({count}) ({color_select}), {date}.' } ], }; // Формат даты const dateFormat = 'ДД.ММ.ГГГГ'; const myTextarea = document.querySelector('textarea'); if (myTextarea) { console.log('textarea найдена'); const blogId = getBlogId(); const availableTemplates = templates[blogId] || []; const templateContainer = document.createElement('div'); templateContainer.id = 'template-container'; myTextarea.parentNode.insertBefore(templateContainer, myTextarea.nextSibling); const templateSelect = document.createElement('select'); templateSelect.id = 'templateSelect'; availableTemplates.forEach((template, index) => { const option = document.createElement('option'); option.value = index; option.text = template.name; templateSelect.appendChild(option); }); templateContainer.appendChild(templateSelect); templateSelect.addEventListener('change', () => { const selectedIndex = templateSelect.value; const selectedTemplate = availableTemplates[selectedIndex].template; renderTemplate(selectedTemplate); }); const dateOffsetLabel = document.createElement('label'); dateOffsetLabel.textContent = 'Смещение даты:'; dateOffsetLabel.htmlFor = 'dateOffset'; templateContainer.appendChild(dateOffsetLabel); const dateOffsetInput = document.createElement('input'); dateOffsetInput.type = 'number'; dateOffsetInput.id = 'dateOffset'; dateOffsetInput.value = 0; templateContainer.appendChild(dateOffsetInput); const fillButton = document.createElement('button'); fillButton.textContent = 'Заполнить шаблон'; fillButton.id = 'fillTemplateButton'; fillButton.type = 'button'; templateContainer.appendChild(fillButton); dateOffsetInput.addEventListener('input', () => { const template = availableTemplates[templateSelect.value].template; if (template.includes('{date}')) { renderTemplate(template); } }); fillButton.addEventListener('click', () => { fillButtonClickCount++; console.log('Кнопка "Заполнить шаблон" нажата, счетчик:', fillButtonClickCount); const templateId = parseInt(document.getElementById('templateSelect').value); console.log('templateId:', templateId); const selectedTemplate = availableTemplates[templateId]; console.log('selectedTemplate:', selectedTemplate); const data = {}; const inputElements = templateContainer.querySelectorAll('.template-field input, .template-field select'); inputElements.forEach(input => { data[input.id] = input.value; }); console.log('data:', data); data['date'] = formatDate(getOffsetDate(parseInt(dateOffsetInput.value) || 0), dateFormat); let basePoints = 0; const pointSelectors = ['item_select', 'color_select']; // Список селекторов с баллами for (const selector of pointSelectors) { if (data[selector]) { basePoints = itemPoints[data[selector]] || 0; break; // Берем баллы первого найденного селектора } } data.points = basePoints; if (data.count) { data.points *= parseInt(data.count); } let filledTemplate = selectedTemplate.template; for (const key in data) { filledTemplate = filledTemplate.replace(new RegExp(`{${key}}`, 'g'), data[key]); } if (fillButtonClickCount === 1) { myTextarea.value = filledTemplate; } else { myTextarea.value += '\n' + filledTemplate; } }); let itemPoints = {}; fetch('https://raw.githubusercontent.com/Sirotkin1/points-data/refs/heads/main/points.json') .then(response => response.json()) .then(data => { itemPoints = data; console.log('Баллы загружены:', itemPoints); if (availableTemplates.length > 0) { renderTemplate(availableTemplates[0].template); } }) .catch(error => console.error('Ошибка загрузки JSON:', error)); function renderTemplate(template) { const prevTemplateField = templateContainer.querySelector('.template-field'); if (prevTemplateField) { prevTemplateField.remove(); } const templateParts = template.split(/(\{[a-z_]+\})/); const templateField = document.createElement('div'); templateField.classList.add('template-field'); const inputCreators = { 'id': () => { const input = document.createElement('input'); input.type = 'text'; return input; }, 'screenshot': () => { const input = document.createElement('input'); input.type = 'text'; return input; }, 'count': () => { const input = document.createElement('input'); input.type = 'number'; input.value = 1; input.min = 1; return input; }, 'color_select': () => { const select = document.createElement('select'); const selectedTemplateName = availableTemplates[templateSelect.value].name; let colors = Object.keys(itemPoints); if (selectedTemplateName === 'Очередь на перо' || selectedTemplateName === 'Выкуп перьев') { colors = colors.filter(key => key.includes('перо')); } colors.forEach(color => { const option = document.createElement('option'); option.value = color; option.text = color; select.appendChild(option); }); return select; }, 'item_select': () => { const select = document.createElement('select'); const selectedTemplateName = availableTemplates[templateSelect.value].name; let items = Object.keys(itemPoints); if (selectedTemplateName === 'Очередь на перо' || selectedTemplateName === 'Выкуп перьев') { return select; // Возвращаем пустой select } items.forEach(item => { const option = document.createElement('option'); option.value = item; option.text = item; select.appendChild(option); }); return select; }, 'shell_type': () => { const select = document.createElement('select'); const types = ['обычная', 'блестящая', 'редкая']; types.forEach(type => { const option = document.createElement('option'); option.value = type; option.text = type; select.appendChild(option); }); return select; }, 'location': () => { const input = document.createElement('input'); input.type = 'text'; input.placeholder = 'Местоположение'; return input; }, 'time': () => { const input = document.createElement('input'); input.type = 'time'; return input; }, 'checkbox_option': () => { const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; return checkbox; }, 'range_value': () => { const input = document.createElement('input'); input.type = 'range'; input.min = 0; input.max = 100; return input; } }; templateParts.forEach((part) => { if (part.startsWith('{')) { const variableName = part.slice(1, -1); const creator = inputCreators[variableName]; if (creator) { const inputElement = creator(); inputElement.id = variableName; templateField.appendChild(inputElement); } } else { const textSpan = document.createElement('span'); textSpan.innerHTML = part.replace(/\[\[n\]\\`l\\`\[\/n\]/g, '[n]`l`[/n]'); templateField.appendChild(textSpan); } }); templateContainer.appendChild(templateField); getUserIdFromPage().then(userId => { if (userId) { const idInput = templateContainer.querySelector('#id'); if (idInput) { idInput.value = userId; } } }); updateDateLabel(); } function formatDate(date, format) { const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); return format.replace('ГГГГ', year).replace('ММ', month).replace('ДД', day); } function getOffsetDate(offset) { const today = new Date(); const offsetDate = new Date(today); offsetDate.setDate(today.getDate() + offset); return offsetDate; } function updateDateLabel() { const offset = parseInt(dateOffsetInput.value) || 0; const offsetDate = getOffsetDate(offset); console.log('Текущая дата:', formatDate(offsetDate, dateFormat)); } function getBlogId() { const match = window.location.pathname.match(/\/blog(\d+)/); if (match) { return 'blog' + match[1]; } return null; } } })();