1. Идея не должна нарушать правила форума, а также правила данного раздела. 2. Предлагаемое дополнение не должно дублировать уже существующие решения в этом разделе — убедитесь, что аналогичной реализации ещё нет. 3. Идея должна быть реализуема в рамках пользовательского дополнения, а не касаться внутреннего устройства форума. Для таких предложений существует отдельный раздел с предложениями. Шаблон для оформления: 1. Название 2. Суть идеи: Что должно делать дополнение? 3. Зачем это нужно: Какую проблему решает или что упрощает? 4. Как можно реализовать: userScripts, Расширение, Телеграм-Бот (если знаете) 5. Куда применяется: На какие страницы форума или процессы влияет (профиль, темы, сообщения и т.д.). Пример оформления 1. Поиск мультиаккаунтов по общим IP 2. Создать дополнение, которое будет автоматически анализировать общие IP-адреса пользователей и визуально отмечать возможные мультиаккаунты прямо в профилях или на других страницах. 3. Упрощает модерацию, экономит время 4. Userscript 5. Профили пользователей, мини-профили при наведении, список пользователей онлайн. Для разработчиков: Если вы реализовали какую-то идею — прикрепите ссылку на дополнение в ответ на сообщение с идеей. Сообщение не по форме - удаление/баллы
umikud, раньше приходилось мониторить предложения для форума чтобы их реализовать в виде дополнений. Хорошая идея была выделить это в отдельную тему раздела
1. Убийца накрутчиков 2. Дополнение будет добавлять кнопку, которая будет сортировать участников в розыгрыше не как сейчас по дате реги участника, а по моменту когда он проучаствовал 3. Это помогает отсеять всех кто проучастовал с ау в розыгрыше и помогает в поиске тех кто специально накрутил симпатии для участия в розыгрыше 4. Расширение 5. Розыгрыши
klopybrittan, держи костыльную Bерсию, каждую страницу Bручную смотреть надо, но уже удобнее Снизу отображаются ласт участия смотреть тут, например https://lolz.live/threads/8495486/contest-users // ==UserScript== // @name Lolz.live Contest Sorter (100% Working) // @namespace http://tampermonkey.net/ // @version 1.2 // @description Надежный сбор и сортировка участников конкурса // @author Your Name // @match https://lolz.live/threads/*/contest-users* // @grant none // ==/UserScript== (function() { 'use strict'; // Ждем полной загрузки страницы setTimeout(function() { createInterface(); }, 1000); function createInterface() { // Проверяем, есть ли уже наша кнопка if (document.getElementById('contestSorterBtn')) return; // Создаем кнопку const btn = document.createElement('button'); btn.id = 'contestSorterBtn'; btn.textContent = 'Сортировать участников'; btn.style = ` background: #4CAF50; color: white; border: none; padding: 10px 15px; border-radius: 4px; font-weight: bold; cursor: pointer; margin: 10px; position: fixed; top: 20px; right: 20px; z-index: 9999; `; // Создаем статус const status = document.createElement('div'); status.id = 'contestSorterStatus'; status.style = ` position: fixed; top: 60px; right: 20px; background: white; padding: 10px; border-radius: 4px; box-shadow: 0 0 10px rgba(0,0,0,0.2); z-index: 9998; max-width: 300px; `; document.body.appendChild(btn); document.body.appendChild(status); btn.addEventListener('click', startProcessing); } async function startProcessing() { const btn = document.getElementById('contestSorterBtn'); const status = document.getElementById('contestSorterStatus'); btn.disabled = true; status.innerHTML = 'Начинаем сбор участников...'; try { // Собираем всех участников const allUsers = await getAllUsers(); if (allUsers.length === 0) { status.innerHTML = 'Участники не найдены. Проверьте структуру страницы.'; return; } // Сортируем по времени allUsers.sort((a, b) => a.timestamp - b.timestamp); // Показываем результаты showResults(allUsers); } catch (error) { console.error('Ошибка:', error); status.innerHTML = 'Ошибка: ' + error.message; } finally { btn.disabled = false; } } async function getAllUsers() { const status = document.getElementById('contestSorterStatus'); const users = []; let page = 1; let hasMore = true; const baseUrl = window.location.href.split('?')[0]; // Сначала собираем с текущей страницы users.push(...getUsersFromPage(document)); // Затем проверяем другие страницы while (hasMore) { status.innerHTML = `Проверяем страницу ${page}...`; const nextPageUrl = `${baseUrl}/contest-users?page=${page + 1}`; const pageExists = await checkPageExists(nextPageUrl); if (!pageExists) break; const nextPageHtml = await fetchPage(nextPageUrl); const nextPageDoc = new DOMParser().parseFromString(nextPageHtml, 'text/html'); users.push(...getUsersFromPage(nextPageDoc)); page++; } return users; } function getUsersFromPage(doc) { return Array.from(doc.querySelectorAll('li.primaryContent.memberListItem')).map(item => { const timeElement = item.querySelector('.DateTime'); const usernameElement = item.querySelector('.username span'); return { html: item.outerHTML, timestamp: timeElement ? parseInt(timeElement.dataset.time) : 0, username: usernameElement ? usernameElement.textContent.trim() : 'Без имени' }; }); } async function checkPageExists(url) { try { const response = await fetch(url, { method: 'HEAD' }); return response.ok; } catch { return false; } } async function fetchPage(url) { const response = await fetch(url); return await response.text(); } function showResults(users) { const status = document.getElementById('contestSorterStatus'); status.innerHTML = `Найдено участников: ${users.length}. Создаем список...`; // Создаем контейнер для результатов const resultsContainer = document.createElement('div'); resultsContainer.id = 'contestSorterResults'; resultsContainer.style = ` position: fixed; top: 100px; right: 20px; bottom: 20px; width: 400px; background: white; overflow-y: auto; padding: 20px; box-shadow: 0 0 20px rgba(0,0,0,0.3); z-index: 9997; `; // Добавляем заголовок const title = document.createElement('h3'); title.textContent = `Отсортированные участники (${users.length})`; resultsContainer.appendChild(title); // Добавляем список const list = document.createElement('div'); list.style.marginTop = '10px'; users.forEach((user, index) => { const userElement = document.createElement('div'); userElement.style.marginBottom = '15px'; userElement.style.padding = '10px'; userElement.style.border = '1px solid #eee'; userElement.style.borderRadius = '4px'; // Обновляем номер в HTML const updatedHtml = user.html.replace(/Номер: \d+/, `Номер: ${index + 1}`); userElement.innerHTML = updatedHtml; list.appendChild(userElement); }); resultsContainer.appendChild(list); document.body.appendChild(resultsContainer); // Добавляем кнопку закрытия const closeBtn = document.createElement('button'); closeBtn.textContent = 'Закрыть'; closeBtn.style = ` position: fixed; top: 120px; right: 30px; background: #f44336; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; z-index: 9999; `; closeBtn.onclick = () => { document.body.removeChild(resultsContainer); document.body.removeChild(closeBtn); }; document.body.appendChild(closeBtn); status.innerHTML = `Сортировка завершена. Найдено ${users.length} участников.`; } })(); Code // ==UserScript== // @name Lolz.live Contest Sorter (100% Working) // @namespace http://tampermonkey.net/ // @version 1.2 // @description Надежный сбор и сортировка участников конкурса // @author Your Name // @match https://lolz.live/threads/*/contest-users* // @grant none // ==/UserScript== (function() { 'use strict'; // Ждем полной загрузки страницы setTimeout(function() { createInterface(); }, 1000); function createInterface() { // Проверяем, есть ли уже наша кнопка if (document.getElementById('contestSorterBtn')) return; // Создаем кнопку const btn = document.createElement('button'); btn.id = 'contestSorterBtn'; btn.textContent = 'Сортировать участников'; btn.style = ` background: #4CAF50; color: white; border: none; padding: 10px 15px; border-radius: 4px; font-weight: bold; cursor: pointer; margin: 10px; position: fixed; top: 20px; right: 20px; z-index: 9999; `; // Создаем статус const status = document.createElement('div'); status.id = 'contestSorterStatus'; status.style = ` position: fixed; top: 60px; right: 20px; background: white; padding: 10px; border-radius: 4px; box-shadow: 0 0 10px rgba(0,0,0,0.2); z-index: 9998; max-width: 300px; `; document.body.appendChild(btn); document.body.appendChild(status); btn.addEventListener('click', startProcessing); } async function startProcessing() { const btn = document.getElementById('contestSorterBtn'); const status = document.getElementById('contestSorterStatus'); btn.disabled = true; status.innerHTML = 'Начинаем сбор участников...'; try { // Собираем всех участников const allUsers = await getAllUsers(); if (allUsers.length === 0) { status.innerHTML = 'Участники не найдены. Проверьте структуру страницы.'; return; } // Сортируем по времени allUsers.sort((a, b) => a.timestamp - b.timestamp); // Показываем результаты showResults(allUsers); } catch (error) { console.error('Ошибка:', error); status.innerHTML = 'Ошибка: ' + error.message; } finally { btn.disabled = false; } } async function getAllUsers() { const status = document.getElementById('contestSorterStatus'); const users = []; let page = 1; let hasMore = true; const baseUrl = window.location.href.split('?')[0]; // Сначала собираем с текущей страницы users.push(...getUsersFromPage(document)); // Затем проверяем другие страницы while (hasMore) { status.innerHTML = `Проверяем страницу ${page}...`; const nextPageUrl = `${baseUrl}/contest-users?page=${page + 1}`; const pageExists = await checkPageExists(nextPageUrl); if (!pageExists) break; const nextPageHtml = await fetchPage(nextPageUrl); const nextPageDoc = new DOMParser().parseFromString(nextPageHtml, 'text/html'); users.push(...getUsersFromPage(nextPageDoc)); page++; } return users; } function getUsersFromPage(doc) { return Array.from(doc.querySelectorAll('li.primaryContent.memberListItem')).map(item => { const timeElement = item.querySelector('.DateTime'); const usernameElement = item.querySelector('.username span'); return { html: item.outerHTML, timestamp: timeElement ? parseInt(timeElement.dataset.time) : 0, username: usernameElement ? usernameElement.textContent.trim() : 'Без имени' }; }); } async function checkPageExists(url) { try { const response = await fetch(url, { method: 'HEAD' }); return response.ok; } catch { return false; } } async function fetchPage(url) { const response = await fetch(url); return await response.text(); } function showResults(users) { const status = document.getElementById('contestSorterStatus'); status.innerHTML = `Найдено участников: ${users.length}. Создаем список...`; // Создаем контейнер для результатов const resultsContainer = document.createElement('div'); resultsContainer.id = 'contestSorterResults'; resultsContainer.style = ` position: fixed; top: 100px; right: 20px; bottom: 20px; width: 400px; background: white; overflow-y: auto; padding: 20px; box-shadow: 0 0 20px rgba(0,0,0,0.3); z-index: 9997; `; // Добавляем заголовок const title = document.createElement('h3'); title.textContent = `Отсортированные участники (${users.length})`; resultsContainer.appendChild(title); // Добавляем список const list = document.createElement('div'); list.style.marginTop = '10px'; users.forEach((user, index) => { const userElement = document.createElement('div'); userElement.style.marginBottom = '15px'; userElement.style.padding = '10px'; userElement.style.border = '1px solid #eee'; userElement.style.borderRadius = '4px'; // Обновляем номер в HTML const updatedHtml = user.html.replace(/Номер: \d+/, `Номер: ${index + 1}`); userElement.innerHTML = updatedHtml; list.appendChild(userElement); }); resultsContainer.appendChild(list); document.body.appendChild(resultsContainer); // Добавляем кнопку закрытия const closeBtn = document.createElement('button'); closeBtn.textContent = 'Закрыть'; closeBtn.style = ` position: fixed; top: 120px; right: 30px; background: #f44336; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; z-index: 9999; `; closeBtn.onclick = () => { document.body.removeChild(resultsContainer); document.body.removeChild(closeBtn); }; document.body.appendChild(closeBtn); status.innerHTML = `Сортировка завершена. Найдено ${users.length} участников.`; } })();
1. Отображение переводов на маркет на стриме 2. Суть идеи: должно выводить на стрим сумму ник и комментарий отправившего деньги 3. Зачем это нужно: Удобно читать донаты не заходя на форум 4. Как можно реализовать: без понятия 5. Куда применяется:маркет
1. Название: ??? 2. Суть идеи: дополнение позволяет редактировать профиль так, как только это возможно. то есть, будет возможность замены аватарки, статуса, уника (полностью), описания профиля и закрепа. также, ко всему этому, будет сохранение пресетов того, что вы сделали. также, должна быть полная поддержка мини профиля (если вы вставили фон, то можно будет настроить его видимость в мини профиле) если что, уник будет виден только тогда, когда вы используете это расширение в случае редактирования профиля. в темах он виден не будет, при обычном нахождении в своём профиле также. поэтому это никакой не халявный уник 3. Зачем это нужно: будет полезно для тех, кто хочет попробовать использовать разные варианты оформления профиля без покупки нескольких уников и т.п. (мне как раз и надо) 4. Как можно реализовать: как вам удобно, я в этом не сильно разбираюсь 5. Куда применяется: профиль и возможно сообщения
1 антиоффтопик 2. Удалять все сообщения в оффтопике, в т.ч вновь написанные 3 не надо сидеть и часами удалять старый бред руками 4. Без разницы 5. Оффтопик
1. Название: Честный кубик 2. Суть идеи: два пользователя нажимают на кнопку бросить кубик в выпадающем окне и вписывают сумму, на которую они собираются играть, при согласии автоматически прописываются две команды /dice, тот игрок который проиграл автоматически отправляет сумму победителю 3. Зачем это нужно: предотвращение скама 4. Как можно реализовать: расширение, при подтверждении игры у обоих пользователей проверяется баланс на наличие средств, если денег нет, то хуй там ничо не работает короче 5. Куда применяется: сообщения
umikud,да, я поэтому и уточнил. А если серверная часть будет не от форума, то не каждый будет доверять расширению.
1 - обычные смайлики в чате 2 - вернуть маленькие смайлики в чате лолза, сейчас если отправить смайлик без текста в чат то он становится большим и шакальным, занимает много места 3 - экономия места + красивее выглядит 4 - скрипт на тамперманки 5 - окно чата + полная версия чата
// ==UserScript== // @name lzt chat smile fixxx pro max xxl ultra pro // @namespace http://tampermonkey.net/ // @version 2025-07-10 // @description try to take over the world! // @author silas // @match https://lolz.live/* // @icon https://www.google.com/s2/favicons?sz=64&domain=lolz.live // @grant none // ==/UserScript== (function() { 'use strict'; function replaceClasses() { const elems = document.querySelectorAll('img.mceSmilie.mceSmilieLarge'); elems.forEach(img => { img.classList.remove('mceSmilieLarge'); if (!img.classList.contains('mceSmilie')) { img.classList.add('mceSmilie'); } }); } replaceClasses(); const observer = new MutationObserver(mutations => { mutations.forEach(() => { replaceClasses(); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); JS // ==UserScript== // @name lzt chat smile fixxx pro max xxl ultra pro // @namespace http://tampermonkey.net/ // @version 2025-07-10 // @description try to take over the world! // @author silas // @match https://lolz.live/* // @icon https://www.google.com/s2/favicons?sz=64&domain=lolz.live // @grant none // ==/UserScript== (function() { 'use strict'; function replaceClasses() { const elems = document.querySelectorAll('img.mceSmilie.mceSmilieLarge'); elems.forEach(img => { img.classList.remove('mceSmilieLarge'); if (!img.classList.contains('mceSmilie')) { img.classList.add('mceSmilie'); } }); } replaceClasses(); const observer = new MutationObserver(mutations => { mutations.forEach(() => { replaceClasses(); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); God_likeGL, да я прям сюда залью, вдруг кому еще понадобится