SDL evo2

Extension du jeu seduis-les.fr

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)


    // ==UserScript==
    // @name         SDL evo2
    // @version      0.2
    // @license MIT 
    // @description  Extension du jeu seduis-les.fr
    // @match        *://*.seduis-les.fr/seduire_new.php?scen=*
    // @author       Un nouveau Khey, qui remercie "Un Khey Sûr"
    // @grant        none
    // @namespace https://greasyfork.org/users/706973
    // ==/UserScript==
     
     
    let script = [];
    let path = [];
    let playing = false;
    let queueStep = false;
     
    const core = {
        ready: async () => {
            await utils.waitFor(() => {
                const coco = document.getElementById("coco");
                return coco && coco.style && coco.style["background-image"] && coco.style["background-image"] !== "";
            });
        },
     
        isGameOver: () => {
            const coco = document.getElementById("coco");
            return coco.style["background-image"].includes("go.jpg");
        },
     
        getGame: () => {
            const title = document.querySelector("body > div:nth-child(7) > table > tbody > tr > td > table:nth-child(4) > tbody > tr:nth-child(1) > td:nth-child(2)").innerHTML.split(":")[1].trim();
            const question = document.querySelector("#txtItem > table:nth-child(1) > tbody > tr > td:nth-child(2) > table.style7 > tbody > tr > td").innerText.trim();
            const table = document.querySelectorAll("#txtItem > table:nth-child(1) > tbody > tr > td:nth-child(2) > table:nth-child(2) > tbody > tr > td > a");
            let answers = [];
            let str = question;
     
            for (let elem of table) {
                answers.push(elem.innerText.trim());
            }
     
            answers = answers.sort();
     
            for (let answer of answers) {
                str += answer;
            }
     
            answers = answers.sort();
     
            return {
                title,
                question,
                answers,
                hash: utils.hashCode(str)
            }
        },
     
        getPath: () => {
            return path;
        },
     
        play: () => {
            playing = true;
            core.processScript(core.getGame());
        },
     
        stop: () => {
            queueStep = false;
            playing = false;
        },
     
        step: () => {
            queueStep = true;
            core.processScript(core.getGame());
        },
     
        processScript: (game) => {
            let answer = null;
            let i = 0;
            for (let entry of script) {
                i++;
                if (!entry.h || !entry.r || !entry.q) {
                    alert("invalid line " + i);
                    return;
                }
                if (entry.h === game.hash && entry.q === game.question) {
                    answer = entry.r;
                    break;
                }
            }
     
            const table = document.querySelectorAll("#txtItem > table:nth-child(1) > tbody > tr > td:nth-child(2) > table:nth-child(2) > tbody > tr > td > a");
            for (let elem of table) {
                if (answer && elem.innerText.trim() === answer) {
                    elem.style["color"] = "green";
                    elem.style["font-weight"] = "bold";
                } else {
                    elem.style["color"] = "black";
                    elem.style["font-weight"] = "normal";
                }
            }
     
     
            if (!answer) {
                core.stop();
                const play = document.getElementById("sdl-play");
                const pause = document.getElementById("sdl-pause");
                play.style["display"] = "inline-block";
                pause.style["display"] = "none";
                return;
            };
     
            if (!playing && !queueStep) return;
            else if (queueStep) queueStep = false;
     
            core.choose(answer);
        },
     
        hook: () => {
            const original = window.showText;
            window.showText = async (nb, sco, com, scen) => {
                const prevGame = core.getGame();
                path.push({
                    q: prevGame.question,
                    r: core.getAnswer(nb, sco, com, scen),
                    h: prevGame.hash,
                });
     
                original(nb, sco, com, scen);
     
                let game;
                while ((game = core.getGame()).hash === prevGame.hash)
                    await utils.sleep(10);
     
                if (!core.isGameOver()) {
                    core.processScript(game);
                }
            };
        },
     
        setScript: (json) => {
            script = json;
            core.processScript(core.getGame());
        },
     
        getAnswer: (nb, sco, com, scen) => {
            const table = document.querySelectorAll("#txtItem > table:nth-child(1) > tbody > tr > td:nth-child(2) > table:nth-child(2) > tbody > tr > td > a");
            for (let elem of table) {
                const args = /[^\(]+\(([^\)]+)\)/.exec(elem.getAttribute("onclick"))[1].split(",").map(a => parseInt(a));
                if (args[0] == nb && args[1] == sco && args[2] == com && args[3] == scen)
                    return elem.innerText.trim();
            }
     
            return null;
        },
     
        getArgs: (answer) => {
            const table = document.querySelectorAll("#txtItem > table:nth-child(1) > tbody > tr > td:nth-child(2) > table:nth-child(2) > tbody > tr > td > a");
            for (let elem of table) {
                if (elem.innerText.trim() === answer)
                    return /[^\(]+\(([^\)]+)\)/.exec(elem.getAttribute("onclick"))[1].split(",").map(a => parseInt(a));
            }
     
            return null;
        },
     
        choose: (answer) => {
            const args = core.getArgs(answer);
            if (args === null) {
                console.log("can't find arguments for '" + answer + "'");
                return;
            }
     
            window.showText.apply(null, args);
        }
    }
     
    const gui = {
     
        saveJSON: (data, filename) => {
     
            if (!data) {
                console.error("No data")
                return;
            }
     
            if (typeof data === "object") {
                data = JSON.stringify(data, undefined, 4)
            }
     
            var blob = new Blob([data], {
                    type: "text/json"
                }),
                e = document.createEvent("MouseEvents"),
                a = document.createElement("a")
     
            a.download = filename
            a.href = window.URL.createObjectURL(blob);
            a.dataset.downloadurl = ["text/json", a.download, a.href].join(':')
            e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
            a.dispatchEvent(e)
        },
     
        init: () => {
            const parent = document.querySelector("body > div:nth-child(7) > table > tbody > tr > td > table:nth-child(4) > tbody > tr:nth-child(2) > td:nth-child(2)");
            parent.align = "left";
            parent.style["padding-bottom"] = "5px";
            document.head.innerHTML += `
            <style>
                #sdl {
                    padding: 2px;
                    vertical-align: middle;
                }
     
                #sdl button {
                    cursor: pointer;
                    margin-right: 3px;
                    margin: 0;
                    font-size: 18px;
                }
     
                #sdl-player {
                    vertical-align: middle;
                    margin-left: 10px;
                }
     
                #sdl-pcontainer {
                    height: 30px;
                    vertical-align: middle;
                }
     
                #sdl-pcontainer > p {
                    margin: 0;
                    padding: 0;
                    margin-right: 5px;
                }
     
                #sdl-player, #sdl-player > * {
                    display: inline-block;
                }
     
                #sdl-unload, #sdl-player, #sdl-file, #sdl-pause {
                    display: none;
                }
     
            </style>
            `
     
            parent.innerHTML = `
            <div id="sdl">
                <button id="sdl-save" title="exporter la progression en fichier script"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-cloud-arrow-down-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">  <path fill-rule="evenodd" d="M8 2a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 6.095 0 7.555 0 9.318 0 11.366 1.708 13 3.781 13h8.906C14.502 13 16 11.57 16 9.773c0-1.636-1.242-2.969-2.834-3.194C12.923 3.999 10.69 2 8 2zm2.354 6.854l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 1 1 .708-.708L7.5 9.293V5.5a.5.5 0 0 1 1 0v3.793l1.146-1.147a.5.5 0 0 1 .708.708z"/></svg></button>
                <button id="sdl-load" title="importer un fichier script"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-cloud-arrow-up-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">  <path fill-rule="evenodd" d="M8 2a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 6.095 0 7.555 0 9.318 0 11.366 1.708 13 3.781 13h8.906C14.502 13 16 11.57 16 9.773c0-1.636-1.242-2.969-2.834-3.194C12.923 3.999 10.69 2 8 2zm2.354 5.146l-2-2a.5.5 0 0 0-.708 0l-2 2a.5.5 0 1 0 .708.708L7.5 6.707V10.5a.5.5 0 0 0 1 0V6.707l1.146 1.147a.5.5 0 0 0 .708-.708z"/></svg></button>
                <button id="sdl-unload" title="decharger le script"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-cloud-slash" fill="currentColor" xmlns="http://www.w3.org/2000/svg">  <path fill-rule="evenodd" d="M3.112 5.112a3.125 3.125 0 0 0-.17.613C1.266 6.095 0 7.555 0 9.318 0 11.366 1.708 13 3.781 13H11l-1-1H3.781C2.231 12 1 10.785 1 9.318c0-1.365 1.064-2.513 2.46-2.666l.446-.05v-.447c0-.075.006-.152.018-.231l-.812-.812zm2.55-1.45l-.725-.725A5.512 5.512 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773a3.2 3.2 0 0 1-1.516 2.711l-.733-.733C14.498 11.378 15 10.626 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3c-.875 0-1.678.26-2.339.661zm7.984 10.692l-12-12 .708-.708 12 12-.707.707z"/></svg></button>
                <div id="sdl-player">
                    <div id="sdl-pcontainer"><p id="sdl-script">sdl_scene2.json</p></div>
                    <button id="sdl-play" title="jouer tout"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-play-fill" fill="currentColor"><path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z"/></svg></button>
                    <button id="sdl-pause" title="arrêter"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pause-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">  <path d="M5.5 3.5A1.5 1.5 0 0 1 7 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5zm5 0A1.5 1.5 0 0 1 12 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5z"/></svg></button>
                    <button id="sdl-step" title="jouer une étape"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-skip-end-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">  <path fill-rule="evenodd" d="M12 3.5a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-1 0V4a.5.5 0 0 1 .5-.5z"/>  <path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z"/></svg></button>
                </div>
                <input id="sdl-file" type="file" accept=".json" />
            </div>
            `;
     
            const reader = new FileReader();
     
            const scriptLabel = document.getElementById("sdl-script");
            const player = document.getElementById("sdl-player");
            const file = document.getElementById("sdl-file");
            const load = document.getElementById("sdl-load");
            const unload = document.getElementById("sdl-unload");
            const save = document.getElementById("sdl-save");
            const play = document.getElementById("sdl-play");
            const pause = document.getElementById("sdl-pause");
            const step = document.getElementById("sdl-step");
     
            reader.onload = e => {
                try {
                    core.setScript(JSON.parse(e.target.result));
                    const split = file.value.split("\\");
                    scriptLabel.innerText = split[split.length - 1];
     
                    load.style["display"] = "none";
                    unload.style["display"] = "inline-block";
                    player.style["display"] = "inline-block";
                } catch (e) {
                    alert("can't parse JSON");
                    console.error(e);
                }
            }
     
     
     
            file.addEventListener("change", e => {
                reader.readAsText(e.target.files[0]);
            });
     
            load.addEventListener("click", e => {
                file.click();
            });
     
            unload.addEventListener("click", e => {
                load.style["display"] = "inline-block";
                unload.style["display"] = "none";
                player.style["display"] = "none";
                core.setScript([]);
                core.stop();
            });
     
            save.addEventListener("click", e => {
                gui.saveJSON(core.getPath(), "sdl_" + Math.floor(Date.now() / 1000) + ".json");
            });
     
            play.addEventListener("click", e => {
                play.style["display"] = "none";
                pause.style["display"] = "inline-block";
                core.play();
            });
     
            pause.addEventListener("click", e => {
                play.style["display"] = "inline-block";
                pause.style["display"] = "none";
                core.stop();
            });
     
            step.addEventListener("click", e => {
                core.step();
            });
        }
     
     
     
    }
     
    const utils = {
        sleep: (ms) => {
            return new Promise(resolve => {
                setTimeout(() => resolve(), ms);
            });
        },
     
        waitFor: (fnc) => {
            return new Promise(async resolve => {
                for (;;) {
                    if (fnc() === true) {
                        resolve();
                        return;
                    }
                    await utils.sleep(100);
                }
            });
        },
     
        hashCode: (str) => {
            let hash = 0;
            if (str.length == 0) return hash;
            for (let i = 0; i < str.length; i++) {
                let char = str.charCodeAt(i);
                hash = ((hash << 5) - hash) + char;
                hash = hash & hash;
            }
            return hash;
        }
    }
     
     
    async function run(){
        await core.ready();
     
        if (core.isGameOver())
            return;
     
        core.hook();
        gui.init();
    }
     
    run();