KiitConnect Unlocker 🪽

Free as in beer.

当前为 2024-05-04 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         KiitConnect Unlocker 🪽
// @namespace    http://tampermonkey.net/
// @version      2.0
// @license      MIT
// @description  Free as in beer.
// @author       erucix
// @match        https://www.kiitconnect.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kiitconnect.com
// ==/UserScript==

(function () {
    'use strict';
    // TODO: Make it false in production build or else code won't worlk.

    let devModeFlag = false;

    // If you find this flag as true please make it false.

    // It is only for dev for debugging purpose and won't give you any
    // super powers

    window.onload = function () {
        if (devModeFlag) {
            console.clear();
            console.log("[+] Unlocker Initiated.");
        }

        if (false) {
            let script = document.createElement("script");
            script.src = "http://127.0.0.1:8080/kiit-connect.js";
            document.body.appendChild(script);
        } else {
            // Removes a node and replaces with its clone and helps in removing all event listeners.
            function remove(node) {
                node.classList.remove("text-yellow-500", "cursor-not-allowed");
                let cursorNotAllowedList = [...node.querySelectorAll(".cursor-not-allowed")];

                cursorNotAllowedList.forEach(element=>{
                    element.classList.add("text-cyan-500");
                    element.classList.remove("text-yellow-500", "cursor-not-allowed");
                });

                if (node.innerText == "Not Available") {
                    node.classList.add("whitespace-nowrap", "font-bold", "text-gray-400");
                } else {
                    node.classList.add("text-cyan-500");
                }

                var clonedNode = node.cloneNode(true);
                node.parentNode.replaceChild(clonedNode, node);
            }

            // Its a single paged application so continuously check for change in URL instead of onload.
            setInterval(function () {

                // Check if the script has already been loaded for given semester.
                if (!document.head.classList.contains(location.pathname)) {

                    // Clear all the previous class list.
                    document.head.classList = "";

                    // Add a class value indicating the script has been loaded for this semester.
                    document.head.classList.add(location.pathname);



                    let docRequired; // Type of document required. Can be: notes, pyqs
                    let branchName;  // Name of choosen branch. Can be: cse, csse, csce, it
                    let semesterId;  // Semester representation in number. Can be any between 1 to 6

                    let finalPath = location.pathname;

                    // Assign values only if we have sufficient information in URL.

                    if (finalPath.includes("/academic/PYQS") && finalPath != "/academic/PYQS") {
                        finalPath = finalPath.substring(finalPath.lastIndexOf("/") + 1);
                        finalPath = finalPath.split("-");

                        docRequired = location.search.substring(location.search.lastIndexOf("=") + 1);
                        branchName = finalPath[1].toLowerCase();
                        semesterId = Number(finalPath[2]);

                        // Fetching original source code so that we could get pdf links
                        fetch(location.href)
                            .then(data => data.text())
                            .then(data => {
                                // Making some adjustments to successfully parse it as JSON

                                let response = data.substring(data.lastIndexOf("1d:[\\") - 23);
                                response = response.replace("self.__next_f.push(", "");
                                response = response.substring(0, response.lastIndexOf(")</script>"));

                                let firstLevelRefined = JSON.parse(response);
                                let secondLevelRefined = firstLevelRefined[1];
                                secondLevelRefined = secondLevelRefined.substring(3);

                                let thirdLevelRefined = JSON.parse(secondLevelRefined);

                                let finalRefined = thirdLevelRefined[3].children[3].data.semesters[0].subjects;


                                if (docRequired == "pyqs") {
                                    // Sort the list according to year
                                    finalRefined.forEach(element => {
                                        element.pyqs.sort((a, b) => {
                                            return Number(a.year) - Number(b.year);
                                        })
                                    });

                                    if (devModeFlag) {
                                        console.log(finalRefined);
                                    }

                                    let containerTables = document.querySelectorAll("table");

                                    // Used for storing loaded table indexes. SO don't touch the table
                                    // again later.
                                    let storedIndexArray = [];

                                    containerTables.forEach((element) => {
                                        let tableRowItems = [...element.querySelectorAll("tr")];

                                        // Since the first 'tr' is table header

                                        tableRowItems.shift();

                                        // Find a table such that the [numbers of paper we have] = [number of rows in table]
                                        // This reduces hassle of creating a new table

                                        let index = 0;

                                        for (let i = 0; i < finalRefined.length; i++) { //           Here we dont touch the loaded table
                                            if (finalRefined[i].pyqs.length == tableRowItems.length && !storedIndexArray.includes(i)) {
                                                index = i;
                                                storedIndexArray.push(i);
                                                break;
                                            }
                                        }

                                        let choosenSubject = finalRefined[index].pyqs;


                                        // Overwrite the 'td' values by our better sorted list
                                        tableRowItems.forEach((item, index1) => {
                                            let tdList = item.querySelectorAll("td");

                                            tdList[0].innerText = choosenSubject[index1].year;
                                            tdList[1].innerText = choosenSubject[index1].type;

                                            let anchor1 = tdList[2].querySelector("a");
                                            anchor1.innerText = choosenSubject[index1].name;
                                            anchor1.href = "https://drive.google.com/file/d/" + choosenSubject[index1].Question;

                                            // Replace the anchor
                                            remove(anchor1);

                                            let anchor2 = tdList[3].querySelector("a");

                                            if (choosenSubject[index1].solution != null) {
                                                if (anchor2 == null) {
                                                    anchor2 = document.createElement("a");
                                                    anchor2.target = "_blank";

                                                    tdList[3].innerText = "";
                                                    tdList[3].appendChild(anchor2);
                                                }

                                                anchor2.innerText = "Solution";
                                                anchor2.href = "https://drive.google.com/file/d/" + choosenSubject[index1].solution;
                                            } else {
                                                if (anchor2 != null) {
                                                    anchor2.innerHTML = "Not Available";
                                                }
                                            }

                                            if (anchor2 != null) {
                                                remove(anchor2);
                                            }

                                        });
                                    });
                                } else if (docRequired == "notes") {
                                    let response = data.substring(data.lastIndexOf("1d:[\\") - 23);
                                    response = response.replace("self.__next_f.push(", "");
                                    response = response.substring(0, response.lastIndexOf(")</script>"));

                                    let firstLevelRefined = JSON.parse(response);
                                    let secondLevelRefined = firstLevelRefined[1];
                                    secondLevelRefined = secondLevelRefined.substring(3);

                                    let thirdLevelRefined = JSON.parse(secondLevelRefined);

                                    let finalRefined = thirdLevelRefined[3].children[3].data.semesters[0].subjects;

                                    if(devModeFlag){
                                        console.log(finalRefined);
                                    }

                                    let subjectNoteContainer = [...document.querySelector("main").querySelector("div").querySelector("div").childNodes];

                                    // Since first one is unwanted jargon div.
                                    subjectNoteContainer.shift();

                                    // Store manipulated div that should not be re-touched.

                                    let storedIndexArray = [];

                                    subjectNoteContainer.forEach(element => {
                                        let anchorElementList = element.querySelectorAll("a");
                                        let index = 0;

                                        for (let i = 0; i < finalRefined.length; i++){
                                            if(finalRefined[i].notes.length == anchorElementList.length && !storedIndexArray.includes(i)){
                                                index = i;
                                                storedIndexArray.push(i);
                                                break;
                                            }
                                        }

                                        let currentSubjectIndex = finalRefined[index].notes;

                                        console.log(anchorElementList);

                                        [...anchorElementList].forEach((element, index1) => {
                                            element.querySelector("h1").innerText = currentSubjectIndex[index1].name;
                                            element.href = "https://drive.google.com/file/d/" + currentSubjectIndex[index1].Notes;

                                            remove(element);
                                        });
                                    });
                                }
                            });
                    }

                    // Remove all get premium buttons from site.
                    setTimeout(function () {
                        let premiumButtons = document.querySelectorAll("a[href='/premiuminfo']");
                        premiumButtons.forEach(item => item.remove());

                    }, 1000);
                }
            }, 500);
        }
    }
})();