Autodarts Lobby Filter Pro

Lobby Filter Pro mit optionalen AVG-Rahmen, horizontal ausgerichtetes Menü und korrektem Preset/Reset/Save-Button inklusive Frame-Checkbox

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Autodarts Lobby Filter Pro
// @namespace    http://tampermonkey.net/
// @version      6.0
// @description  Lobby Filter Pro mit optionalen AVG-Rahmen, horizontal ausgerichtetes Menü und korrektem Preset/Reset/Save-Button inklusive Frame-Checkbox
// @match        https://play.autodarts.io/*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js
// @grant        GM_addStyle
// @run-at       document-idle
// ==/UserScript==
 
(function() {
"use strict";
 
const STORAGE_KEY = "autodartsPreset_v2";
 
let preset = {
    gamemode: "501",
    minavg: "50",
    maxavg: "All",
    sidomode: "SI-DO",
    stableList: true,
    hideEmpty: true,
    hideNoAvg: true,
    onlyPlus: false,
    hideDuplicates: true,
    highlightAVG: true // Frame-Checkbox speichern
};
 
let defaults = {
    gamemode: "All",
    minavg: "All",
    maxavg: "All",
    sidomode: "All",
    stableList: true,
    hideEmpty: false,
    hideNoAvg: false,
    onlyPlus: false,
    hideDuplicates: false,
    highlightAVG: false // Standard für Frame
};
 
let scriptInitialized = false;
let observer = null;
let initObserver = null;
 
function checkPage() {
    if(/^\/lobbies\/?$/.test(location.pathname)) {
        if(!scriptInitialized){ scriptInitialized=true; initScript(); }
    } else {
        scriptInitialized=false;
        if(observer) observer.disconnect();
        if(initObserver) initObserver.disconnect();
        $(".tm_menu").remove();
    }
}
 
const pushState = history.pushState;
history.pushState = function() { pushState.apply(history, arguments); setTimeout(checkPage,50); };
window.addEventListener("popstate", checkPage);
setTimeout(checkPage,200);
 
function initScript() {
 
    let savedPreset = localStorage.getItem(STORAGE_KEY);
    if(savedPreset) {
        try { preset = JSON.parse(savedPreset); }
        catch(e) { console.warn("Preset konnte nicht geladen werden"); }
    }
 
    GM_addStyle(`
        .hide { display: none !important; }
        #gamemode, #avgmenumin, #avgmenumax, #sidomenu {
            width: 75px; padding:4px; box-sizing:border-box;
        }
        #avgmenumin, #avgmenumax { width: 55px; }
        .tm_menu {
            display: flex;
            margin-top: 10px;
            align-items: flex-start;
            gap: 12px;
            font-size: 13px;
        }
        .tm_menu > div {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .tm_menu > div input[type="checkbox"] {
            margin-top: 8px;
        }
        #presetbtn { color:white; border:none; border-radius:4px; font-weight:600; padding:5px 10px; cursor:pointer; }
        #presetbtn[data-mode="preset"] { background:#38a169; }
        #presetbtn[data-mode="reset"] { background:#e53e3e; }
        #presetbtn[data-mode="save"] { background:#3182ce; }
    `);
 
    let gamemode = "All", minavg="All", maxavg="All", sidomode="All";
    let stableList=true, hideEmpty=true, hideNoAvg=true, onlyPlus=false, hideDuplicates=true;
    let highlightAVG = true;
    let knownCards=new WeakSet();
    let seenLobbyKeys=new Map();
    let presetChanged = false;
 
    function applyFilter(card){
        $(card).removeClass("hide");
        if(hideDuplicates){
            let key=[];
            $(card).find(".chakra-stack").each(function(){ key.push($(this).text().replace(/\s+/g," ").trim()); });
            key = key.join("|");
            if(seenLobbyKeys.has(key)){
                let oldCard=seenLobbyKeys.get(key);
                if(oldCard && oldCard!==card){ $(oldCard).addClass("hide"); }
                seenLobbyKeys.set(key,card);
            } else { seenLobbyKeys.set(key,card); }
        }
        if(hideEmpty && !card.querySelector(".ad-ext-player-name")){ $(card).addClass("hide"); return; }
        if(hideNoAvg && !card.querySelector(".chakra-badge")){ $(card).addClass("hide"); return; }
 
        let html = card.innerHTML;
        let avgText = $(card).find(".chakra-badge").eq(0).text();
        let avg = parseInt(avgText);
 
        if(onlyPlus && !html.includes("chakra-image css-l5at91")){ $(card).addClass("hide"); return; }
        if(gamemode !== "All" && !html.includes(gamemode+"</span>")){ $(card).addClass("hide"); return; }
        if(sidomode !== "All" && !html.includes(sidomode+"</span>")){ $(card).addClass("hide"); return; }
        if(minavg !== "All" && avg < parseInt(minavg)){ $(card).addClass("hide"); return; }
        if(maxavg !== "All" && avg > parseInt(maxavg)){ $(card).addClass("hide"); return; }
    }
 
    function applyHighlight(card){
        const badge = card.querySelector(".chakra-badge");
        if(!badge) return;
        if(!highlightAVG){ badge.style.border=""; return; }
 
        let avg = parseInt(badge.innerText);
        if(avg >= 70){ badge.style.border="3px solid rgb(250,240,137)"; }
        else if(avg===60 || avg===65){ badge.style.border="3px solid rgb(214,188,250)"; }
        else if(avg===50 || avg===55){ badge.style.border="3px solid rgb(123,218,210)"; }
        else if(avg===40 || avg===45){ badge.style.border="3px solid rgb(154,230,180)"; }
        else{ badge.style.border="3px solid white"; }
    }
 
    function refilterAll(){
        seenLobbyKeys.clear();
        document.querySelectorAll(".chakra-card").forEach(card=>{ applyFilter(card); applyHighlight(card); });
    }
 
    function processLobby(card){
        if(knownCards.has(card)) return;
        knownCards.add(card);
        if(stableList){ const parent=card.parentNode; if(parent && parent.lastElementChild!==card) parent.appendChild(card); }
        applyFilter(card); applyHighlight(card);
    }
 
    observer = new MutationObserver(mutations=>{
        mutations.forEach(m=>{
            m.addedNodes.forEach(node=>{
                if(node.nodeType!==1) return;
                if(node.classList?.contains("chakra-card")) processLobby(node);
                node.querySelectorAll?.(".chakra-card").forEach(processLobby);
            });
        });
        refilterAll();
    });
    observer.observe(document.body,{childList:true,subtree:true});
 
    function createMenu(){
        if($("#gamemode").length) return;
        if(!$(".chakra-heading").length) return;
 
        const menuHTML = `
<div class="tm_menu">
    <div title="Spiel auswählen"><label>Game</label><select id="gamemode">
        <option>All</option><option>501</option><option>301</option><option>Cricket</option><option>Tactics</option>
        <option>Bermuda</option><option>Shanghai</option><option>Gotcha</option><option>ATC</option>
        <option>RTW</option><option>Random Checkout</option><option>CountUp</option><option>Bob's 27</option>
        <option>Killer</option></select></div>
 
    <div title="Minimaler Average"><label>Min Avg</label><select id="avgmenumin">
        <option>All</option><option>25</option><option>30</option><option>35</option><option>40</option><option>45</option>
        <option>50</option><option>55</option><option>60</option><option>65</option><option>70</option></select></div>
 
    <div title="Maximaler Average"><label>Max Avg</label><select id="avgmenumax">
        <option>All</option><option>30</option><option>35</option><option>40</option><option>45</option>
        <option>50</option><option>55</option><option>60</option><option>65</option><option>70</option><option>75</option></select></div>
 
    <div title="CheckIn/CheckOut"><label>Mode</label><select id="sidomenu">
        <option>All</option><option>SI-SO</option><option>SI-DO</option><option>SI-MO</option>
        <option>DI-SO</option><option>DI-DO</option><option>DI-MO</option>
        <option>MI-SO</option><option>MI-DO</option><option>MI-MO</option></select></div>
 
    <div title="Neue Lobbies immer ans Ende">Sort<input type="checkbox" id="stablelist" checked></div>
    <div title="Blendet Lobbies ohne Spieler aus">Empty<input type="checkbox" id="hideempty" checked></div>
    <div title="Blendet Spieler ohne AVG">No_AVG<input type="checkbox" id="hidenoavg" checked></div>
    <div title="Nur Autodarts Plus">Plus<input type="checkbox" id="onlyplus"></div>
    <div title="Blendet identische Lobbies aus">No_Dup<input type="checkbox" id="hideduplicates"></div>
    <div title="Rahmen ein-/ausschalten">Frame<input type="checkbox" id="highlightavg" checked></div>
    <div title="Preset speichern/laden"><button id="presetbtn" data-mode="preset">Preset</button></div>
</div>
`;
 
        $(".chakra-heading").after(menuHTML);
 
        $("#highlightavg").on("change", function() { highlightAVG = this.checked; presetChanged=true; $("#presetbtn").text("Save").attr("data-mode","save"); refilterAll(); });
 
        $("#gamemode, #avgmenumin, #avgmenumax, #sidomenu, #stablelist, #hideempty, #hidenoavg, #onlyplus, #hideduplicates").on("change", function() {
            presetChanged = true;
            $("#presetbtn").text("Save").attr("data-mode","save");
            if(this.id==="gamemode") gamemode=this.value;
            if(this.id==="avgmenumin") minavg=this.value;
            if(this.id==="avgmenumax") maxavg=this.value;
            if(this.id==="sidomenu") sidomode=this.value;
            if(this.id==="stablelist") stableList=this.checked;
            if(this.id==="hideempty") hideEmpty=this.checked;
            if(this.id==="hidenoavg") hideNoAvg=this.checked;
            if(this.id==="onlyplus") onlyPlus=this.checked;
            if(this.id==="hideduplicates") hideDuplicates=this.checked;
            refilterAll();
        });
 
        $("#presetbtn").on("click", function(){
            let mode = $(this).attr("data-mode");
            if(mode==="preset"){ loadPreset(false); }
            else if(mode==="save"){ savePreset(); }
            else if(mode==="reset"){ resetFilters(); }
        });
 
        setTimeout(()=>{ loadPreset(false); },100);
    }
 
    function loadPreset(showSaveButton=true){
        gamemode=preset.gamemode; minavg=preset.minavg; maxavg=preset.maxavg; sidomode=preset.sidomode;
        stableList=preset.stableList; hideEmpty=preset.hideEmpty; hideNoAvg=preset.hideNoAvg;
        onlyPlus=preset.onlyPlus; hideDuplicates=preset.hideDuplicates; highlightAVG=preset.highlightAVG;
 
        $("#gamemode").val(gamemode); $("#avgmenumin").val(minavg); $("#avgmenumax").val(maxavg);
        $("#sidomenu").val(sidomode);
        $("#stablelist").prop("checked",stableList); $("#hideempty").prop("checked",hideEmpty);
        $("#hidenoavg").prop("checked",hideNoAvg); $("#onlyplus").prop("checked",onlyPlus);
        $("#hideduplicates").prop("checked",hideDuplicates); $("#highlightavg").prop("checked",highlightAVG);
 
        refilterAll();
 
        presetChanged = false;
        if(showSaveButton){
            $("#presetbtn").text("Save").attr("data-mode","save");
        } else {
            $("#presetbtn").text("Preset").attr("data-mode","preset");
        }
    }
 
    function savePreset(){
        preset = { gamemode, minavg, maxavg, sidomode, stableList, hideEmpty, hideNoAvg, onlyPlus, hideDuplicates, highlightAVG };
        localStorage.setItem(STORAGE_KEY, JSON.stringify(preset));
        $("#presetbtn").text("Saved!");
        setTimeout(()=>{ $("#presetbtn").text("Reset").attr("data-mode","reset"); },1000);
        presetChanged = false;
    }
 
    function resetFilters(){
        gamemode=defaults.gamemode; minavg=defaults.minavg; maxavg=defaults.maxavg; sidomode=defaults.sidomode;
        stableList=defaults.stableList; hideEmpty=defaults.hideEmpty; hideNoAvg=defaults.hideNoAvg; onlyPlus=defaults.onlyPlus; hideDuplicates=defaults.hideDuplicates; highlightAVG=defaults.highlightAVG;
 
        $("#gamemode").val(gamemode); $("#avgmenumin").val(minavg); $("#avgmenumax").val(maxavg);
        $("#sidomenu").val(sidomode);
        $("#stablelist").prop("checked",stableList); $("#hideempty").prop("checked",hideEmpty);
        $("#hidenoavg").prop("checked",hideNoAvg); $("#onlyplus").prop("checked",onlyPlus);
        $("#hideduplicates").prop("checked",hideDuplicates); $("#highlightavg").prop("checked",highlightAVG);
 
        refilterAll();
        $("#presetbtn").text("Preset").attr("data-mode","preset");
    }
 
    initObserver = new MutationObserver(()=>{
        createMenu();
        document.querySelectorAll(".chakra-card").forEach(processLobby);
    });
    initObserver.observe(document.body, { childList:true, subtree:true });
}
})();