您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds search bar and pre-made filters, including full relic list. Adds checkbox to hide entered giveaways. Persists through reload
// ==UserScript== // @name GC Giveaway Search/Filters // @version 1.2 // @description Adds search bar and pre-made filters, including full relic list. Adds checkbox to hide entered giveaways. Persists through reload // @author spiderpool1855 // @match https://www.grundos.cafe/giveaways/ // @license MIT // @grant none // @namespace https://greasyfork.org/users/1295622 // ==/UserScript== (function() { 'use strict'; let page = 2; // Start from the first page let loading = false; // Function to disable the page's loadMoreItems function function disablePageLoader() { if (window.loadMoreItems) { console.log('Disabling the page\'s loadMoreItems function.'); window.loadMoreItems = function() { console.log('loadMoreItems function has been disabled.'); }; } else { console.log('loadMoreItems function not found.'); } } function loadAllItems() { if (loading) return; // Prevent overlapping fetches loading = true; const url = `/giveaways/?page=${page}&active=true`; fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest', } }) .then(response => response.json()) .then(data => { const container = document.querySelector('.giveaway-grid-container'); const initialItemCount = container.children.length; container.insertAdjacentHTML('beforeend', data.items_html); const newItemCount = container.children.length; if (newItemCount > initialItemCount) { // Continue loading items if (data.has_next) { page += 1; setTimeout(loadAllItems, 100); // Delay before loading the next page } else { console.log('All items have been loaded.'); disablePageLoader(); // Disable further loading after the last page } } else { console.log('No new items found, stopping.'); disablePageLoader(); // Disable further loading if no new items found } }) .catch(error => { console.error('Error loading more items:', error); }) .finally(() => { loading = false; // Allow the next load to proceed }); } // Start loading all items from the first page loadAllItems(); })(); (function() { 'use strict'; // Pre-made queries - You can add more here and it will add checkboxes for them const queries = ['Paint', 'Potion', 'Stamp', 'Map', 'Negg']; // Relic query list const relicList = ["Air Faerie Crown" , "Air Faerie Token" , "Ancient Lupe Wand" , "Aquatic Gem" , "Army Math Tools" , "Attack Cape" , "Attack Fork" , "Bag of Occult Jelly" , "Battle Plunger" , "Battle Quill" , "Bit of Evil Clown" , "Blizzard Ring" , "Blood Grub" , "Boom Sticks" , "Brain Tree Branch" , "Brain Tree Knife" , "Brain Tree Mace" , "Brain Tree Root" , "Brain Tree Splinters" , "Cabbage of Mystery" , "Candy Club" , "Castle Defenders Shield" , "Castle Defenders Sword" , "Caustic Potion" , "Charles' Torch" , "Cobrall Wand" , "Dark Faerie Dagger" , "Dark Faerie Token" , "Donny's Mallet" , "Earth Faerie Dagger" , "Earth Faerie Token" , "Earth Stone Gem" , "Elephante Lamp" , "Eraser of the Dark Faerie" , "Exploding Space Bugs" , "Faerie Eraser" , "Fat Red Pen" , "Fire Faerie Token" , "Fire Stone Gem" , "Frostbite Dart" , "Fumpu Leaf Medallion" , "Garin's Sword" , "Genie Orb" , "Ghost Lupe Sword" , "Golden Aisha Wand" , "Golden Meepit Statue" , "Golden Pirate Amulet" , "Good Snowball" , "Grarrg Tooth" , "Great Snowball" , "Grundo Gavel" , "Halloween Aisha Bucket" , "Happy Anniversary Negg" , "Happy Negg Eraser" , "Hawk Bracelet" , "Hawk Wand" , "Iced Wand" , "Iceray Bracelet" , "Irregulation Chainmail" , "Jar of Spiders" , "King Kelpbeards Blessing" , "Lava Rock" , "Legendary von Roo Ring" , "Light Faerie Dagger" , "Light Faerie Token" , "Magic Branch" , "Magnus Club" , "Malice Potion" , "Melting Mirror" , "Monotonous Dial" , "Mystical Fish Lobber" , "Mystic Guitar" , "Mystic Jelly Bean Necklace" , "Neutron Wand" , "Nimmo Finger" , "Official Prissy Miss Hair Brush" , "Patched Magic Hat" , "Pear of Disintegration" , "Petpet Bone" , "Platinum Dubloon" , "Poké Ball" , "Power Negg Eraser" , "Pumpkin Stick" , "Radish Bow" , "Rainbow Cybunny Wand" , "Rainbow Kacheek Pendant" , "Rainbow Negg Eraser" , "Rainbow Pteri Feather" , "Reinvented Wheel" , "Ring of the Lost" , "Robo Sloth Fist of Power" , "Royal Wedding Ring" , "Rusty Garden Pitchfork" , "Rutabaga Lance" , "Scarab Amulet" , "Scroll of Ultimate Knowledge" , "Snowager Pendant" , "Snowager Sleep Ray" , "Snow Beast Horn" , "Snowflake Pendant" , "Snowglobe Staff" , "Soul Stone" , "Space Amulet" , "Space Faeries Shield" , "Space Faerie Token" , "Spider Grundo Sword" , "Spirited Fiddle" , "Spooky Slime" , "Squash Club" , "Staff of Brain" , "Starry Scorchio Wand" , "Superior Battle Plunger" , "Trident of Chiazilla" , "Trusty Hand Cannon" , "Tyrannian Amulet" , "Ultra Fire Gem" , "Wand of the Snow Faerie" , "Water Faerie Dagger" , "Water Faerie Token" , "Wind Up Rat" , "Witches Orb" , "Wooden Compass" , "Zucchini Bat"]; // Create the filter div const filterContainer = document.createElement('div'); filterContainer.style.margin = '20px 0'; // Creates searchbar const searchBar = document.createElement('input'); searchBar.setAttribute('type', 'text'); searchBar.setAttribute('placeholder', 'Search giveaways...'); searchBar.style.marginRight = '10px'; searchBar.style.width = '25%'; // Load previous search from localstorage searchBar.value = localStorage.getItem('searchQuery') || ''; // Save current query to local storage and initiates filter searchBar.addEventListener('input', () => { localStorage.setItem('searchQuery', searchBar.value); filterGiveaways(); }); filterContainer.appendChild(searchBar); // Create the "Open" checkbox - Open means that it hides "Entered" giveaways const hideEnteredCheckbox = document.createElement('input'); hideEnteredCheckbox.setAttribute('type', 'checkbox'); hideEnteredCheckbox.setAttribute('id', 'hideEntered'); hideEnteredCheckbox.checked = JSON.parse(localStorage.getItem('hideEntered')) || false; const hideEnteredLabel = document.createElement('label'); hideEnteredLabel.setAttribute('for', 'hideEntered'); hideEnteredLabel.textContent = 'Open'; filterContainer.appendChild(hideEnteredCheckbox); filterContainer.appendChild(hideEnteredLabel); // Save "Open" checkbox status to local storage hideEnteredCheckbox.addEventListener('change', () => { localStorage.setItem('hideEntered', hideEnteredCheckbox.checked); filterGiveaways(); }); // Create checkboxes for pre-made queries queries.forEach(query => { const checkbox = document.createElement('input'); checkbox.setAttribute('type', 'checkbox'); checkbox.setAttribute('id', `filter${query.replace(/\s+/g, '')}`); checkbox.checked = JSON.parse(localStorage.getItem(`filter${query.replace(/\s+/g, '')}`)) || false; const label = document.createElement('label'); label.setAttribute('for', `filter${query.replace(/\s+/g, '')}`); label.textContent = query; filterContainer.appendChild(checkbox); filterContainer.appendChild(label); // Save pre-made query checkbox statuses to local storage checkbox.addEventListener('change', () => { localStorage.setItem(`filter${query.replace(/\s+/g, '')}`, checkbox.checked); filterGiveaways(); }); }); // Create the "Relic" checkbox const relicCheckbox = document.createElement('input'); relicCheckbox.setAttribute('type', 'checkbox'); relicCheckbox.setAttribute('id', 'filterRelic'); relicCheckbox.checked = JSON.parse(localStorage.getItem('filterRelic')) || false; const relicLabel = document.createElement('label'); relicLabel.setAttribute('for', 'filterRelic'); relicLabel.textContent = 'Relic'; filterContainer.appendChild(relicCheckbox); filterContainer.appendChild(relicLabel); // Save "Relic" checkbox status to local storage relicCheckbox.addEventListener('change', () => { localStorage.setItem('filterRelic', relicCheckbox.checked); filterGiveaways(); }); // Insert the filter container const parentElement = document.querySelector('.giveaway-grid-container').parentNode; parentElement.insertBefore(filterContainer, document.querySelector('.giveaway-grid-container')); // Filter function searchBar.addEventListener('input', filterGiveaways); function filterGiveaways() { const query = searchBar.value.toLowerCase(); const hideEntered = hideEnteredCheckbox.checked; const relicCheckboxChecked = relicCheckbox.checked; document.querySelectorAll('.giveaway-item').forEach(item => { let text = item.querySelector('h3')?.textContent.toLowerCase() || ''; const status = item.querySelector('p.state')?.textContent.toLowerCase() || ''; let showItem = true; // Filter by "Open" checkbox if (hideEntered && status.includes('entered')) { showItem = false; } // Filter by pre-made queries if (queries.some(query => { const checkbox = document.getElementById(`filter${query.replace(/\s+/g, '')}`); return checkbox.checked && !text.includes(query.toLowerCase()); })) { showItem = false; } // Filter by "Relic" checkbox const relicMatches = relicList.some(relic => text.includes(relic.toLowerCase())); if (relicCheckboxChecked && !relicMatches) { showItem = false; } // Filter by search query if (query && !text.includes(query)) { showItem = false; } // Show all items if no filters are checked const anyCheckboxChecked = queries.some(q => document.getElementById(`filter${q.replace(/\s+/g, '')}`).checked) || relicCheckboxChecked || hideEntered; if (!anyCheckboxChecked && !query) { showItem = true; } item.style.display = showItem ? '' : 'none'; }); } // Initial filter on page load filterGiveaways(); })();