Greasy Fork

Greasy Fork is available in English.

巴哈動漫電玩通題庫與解答系統

巴哈動漫電玩通題庫與解答系統,蒐集題庫中~

目前为 2019-11-02 提交的版本,查看 最新版本

// ==UserScript==
// @name         巴哈動漫電玩通題庫與解答系統
// @namespace    https://home.gamer.com.tw/moontai0724
// @version      4.0.1
// @description  巴哈動漫電玩通題庫與解答系統,蒐集題庫中~
// @author       moontai0724
// @match        https://forum.gamer.com.tw/B.php*
// @supportURL   https://home.gamer.com.tw/creationDetail.php?sn=3924920
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @connect      script.google.com
// @connect      script.googleusercontent.com
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @resource     quizrp https://raw.githubusercontent.com/moontai0724/UserScripts/master/GamerQuizDB/quizrp.html
// @license      MIT
// ==/UserScript==

(function (jQuery) {
    'use strict';
    // add button to monitor html loading
    jQuery("body").append('<button id="quizrp_html_loaded" style="display: none;"></button>');
    jQuery('#quizrp_html_loaded').on('click', init);

    // load html
    jQuery(GM_getResourceText("quizrp")).insertAfter(".BH-qabox1");

    // variables
    const qabox = jQuery(".BH-rbox.BH-qabox1");
    var quizrp_quiz = {
        sn: qabox.data("quiz-sn"),
        question: encodeURIComponent(qabox.html().replace(/\n/g, '').split('<ul>')[0]),
        options: Array.from(qabox.find("li a").map((index, value) => encodeURIComponent(value.innerText))),
        author: qabox.find("span>a:first").attr("href").match(/gamer.com.tw\/([\s\S]*)/)[1],
        bsn: location.search.split('&').find(value => value.indexOf('bsn') > -1).split('=')[1]
    };

    const BAHAID = document.cookie.split(';').map(value => value.startsWith(' ') ? value.replace(' ', '').split('=', 2) : value.split('=', 2)).find(value => value[0] == 'BAHAID') == undefined ? undefined : document.cookie.split(';').map(value => value.startsWith(' ') ? value.replace(' ', '').split('=', 2) : value.split('=', 2)).find(value => value[0] == 'BAHAID')[1];

    // flag
    var AlreadyAnswered = false;
    var quizrp_show_original_showed = false;

    function init() {
        const qabox = jQuery(".BH-rbox.BH-qabox1");

        // init version
        jQuery("#quizrp_version").html(GM_info.script.version);

        // init auto answer and report status
        if (localStorage.quizrp_autoanswer) {
            jQuery(".quizrp.autoanswer_status").addClass("enable");
            setTimeout(() => autoAnswer(), 3000);
        }

        // Get options and remove original answer function
        qabox.find("li a").removeAttr('href');

        // attach click event
        qabox.find("li a").on("click", event => manualAnswer(quizrp_quiz.options.indexOf(encodeURIComponent(event.target.innerText)) + 1));

        // attach auto answer toggle button
        jQuery("#quizrp_autoanswer_switch").on("click", toggleAutoAnswer);

        // attach show quiz button
        jQuery("#quizrp_show_original_btn").on("click", display_original_quiz);

        // attach hint button
        jQuery("#quizrp_gethint").on("click", getHint);
    }

    // To get hint
    function getHint() {
        DB_get('hint').then(hint => {
            jQuery("#quizrp_gethint").addClass("quizrp hidden");

            if (hint.success) {
                qabox.find(`li:nth-child(${hint.message}) a`).css({ "color": "red", "text-decoration": "line-through" });
                jQuery("#quizrp_hint").css("color", "green").html("提示已獲取。");
            } else {
                jQuery("#quizrp_hint").css("color", "red").html("題庫中無資料。");
            }
        });
    };

    // To show the original QA and ans
    function display_original_quiz() {
        if (quizrp_show_original_showed == false) {
            quizrp_show_original_showed = true;
            jQuery("#quizrp_show_original_btn").addClass("quizrp hidden");
            jQuery(".quizrp.original").removeClass("hidden").html(`題目編號:${quizrp_quiz.sn}<br>原題目:${decodeURIComponent(quizrp_quiz.question)}<ol><li>${quizrp_quiz.options.map(decodeURIComponent).join("</li><li>")}</li></ol>`);
        }

        DB_get('answer').then(async ans => {
            if (!ans.success) {
                ans = await getAnswer();
                if (AlreadyAnswered == false) DB_post(ans, true);
            } else {
                ans = ans.message
            }

            jQuery(`.quizrp.original li`).css({ "color": "red", "text-decoration": "line-through" });
            jQuery(`.quizrp.original li:nth-child(${ans})`).css({ "color": "green", "font-weight": "bold", "text-decoration": "" });
        });
    }

    // Get a return of answer or a space
    function DB_get(action) {
        return new Promise(function (resolve, reject) {
            GM_xmlhttpRequest({
                method: "GET",
                url: "https://script.google.com/macros/s/AKfycbxYKwsjq6jB2Oo0xwz4bmkd3-5hdguopA6VJ5KD/exec?type=" + action + "&sn=" + quizrp_quiz.sn,
                onload: data => {
                    console.log(data.response)
                    resolve(JSON.parse(data.response))
                },
                onerror: reject
            });
        });
    }

    // Start report to database
    function DB_post(this_answered, correctness) {
        return new Promise((resolve, reject) => {
            qabox.css("background-color", "#cccccc");
            GM_xmlhttpRequest({
                method: 'POST',
                url: 'https://script.google.com/macros/s/AKfycbxYKwsjq6jB2Oo0xwz4bmkd3-5hdguopA6VJ5KD/exec',
                data: JSON.stringify({
                    "version": GM_info.script.version,
                    "sn": quizrp_quiz.sn,
                    "question": quizrp_quiz.question,
                    "options": quizrp_quiz.options,
                    "BoardSN": quizrp_quiz.bsn,
                    "reporter": BAHAID,
                    "author": quizrp_quiz.author,
                    "this_answered": this_answered,
                    "correctness": correctness
                }),
                onload: function (data) {
                    data = JSON.parse(data.response);

                    jQuery(".quizrp.report_status").html(data.message);

                    // if success, add class to status
                    if (data.success)
                        jQuery(".quizrp.report_status").addClass("success");

                    // remove loading style
                    qabox.css("background-color", "");
                }
            });
        })
    }

    function manualAnswer(option) {
        if (BAHAID) {
            AlreadyAnswered = true;
            getCSRFToken().then(CSRFToken => answerQuiz(option, CSRFToken).then(correctness => {
                if (correctness)
                    DB_post(option, correctness);
            }));
        } else {
            if (window.confirm('您尚未登入!'))
                location.href = 'https://user.gamer.com.tw/login.php';
        }
    }

    function autoAnswer() {
        if (AlreadyAnswered == false) {
            AlreadyAnswered = true;
            DB_get('checkExisting').then(function (data) {
                if (data.success) {
                    jQuery(".quizrp.report_status").html('題庫中有答案,無須回報。').css("color", "green");
                } else {
                    getAnswer().then(ans => DB_post(ans, true).then(display_original_quiz));
                }
            });
        }
    }

    function toggleAutoAnswer() {
        if (localStorage.quizrp_autoanswer) {
            localStorage.removeItem('quizrp_autoanswer');
            jQuery(".quizrp.autoanswer_status.enable").removeClass("enable");
        } else {
            localStorage.setItem('quizrp_autoanswer', 'true');
            jQuery(".quizrp.autoanswer_status").addClass("enable");

            autoAnswer();
        }
    }

    function getAnswer() {
        return new Promise(function (resolve, reject) {
            getCSRFToken().then(function (CSRFToken) {
                (function next(ans) {
                    return new Promise(async function (resolve, reject) {
                        if (await answerQuiz(ans, CSRFToken, false))
                            resolve(ans);
                        else if (ans > 4)
                            reject();
                        else
                            next(Number(ans) + 1).then(ans => resolve(ans));
                    });
                })(1).then(ans => {
                    resolve(ans);
                }, reject);
            }, reject);
        });
    }

    function answerQuiz(ans, CSRFToken, setQABox = true) {
        return new Promise(function (resolve, reject) {
            jQuery.get("/ajax/quiz_answer.php", { sn: quizrp_quiz.sn, o: ans, token: CSRFToken }).then(data => {
                if (setQABox)
                    qabox.css("text-align", "center").html(data);
                resolve(/答對/.test(data), data);
            });
        });
    }

    function getCSRFToken() {
        return new Promise(function (resolve, reject) {
            jQuery.ajax({
                type: "GET",
                url: "/ajax/getCSRFToken.php",
                cache: false
            }).then(resolve, reject);
        })
    }
})(jQuery);