Vjudge Submission from Luogu and AT

Add luogu submission to vjudge contest

// ==UserScript==
// @name         Vjudge Submission from Luogu and AT
// @namespace    https://smkttl.github.io
// @version      2.0
// @description  Add luogu submission to vjudge contest
// @author       limesarine
// @match        https://vjudge.net/contest/*
// @match        https://www.vjudge.net/contest/*
// @match        https://vjudge.net.cn/contest/*
// @match        https://www.vjudge.net.cn/contest/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=vjudge.net
// @license      CC-BY-NC-ND
// @grant        none
// ==/UserScript==

let good=false,alerted=false,aborted=false,logging=true,expanded=false;

function limesarine_expand()
{
    if(expanded) return;
    expanded=true;
    let dialog=document.createElement("div");
    dialog.style.position="fixed";
    dialog.style.top="25vh";
    dialog.style.left="25vw";
    dialog.style.width="50vw";
    dialog.style.height="50vh";
    dialog.style.borderRadius="8px";
    dialog.style.boxShadow="0 1px 6px rgba(0, 0, 0, .2)";
    dialog.style.borderColor="#F0F8FF";
    dialog.style.backgroundColor="#E0E8FC";
    dialog.style.fontSize="90%";
    dialog.style.padding="20px";
    dialog.style.lineHeight="0px";
    dialog.innerHTML=`
  <h2>设置</h2>
  <p><input type="checkbox" class="lsCheckbox" name="useLG" id="useLG"></input><label for="useLG" class="lsCheckboxLabel">启用洛谷</label></p>
  <span id="LGdata">
    <p>
      <label for="uid">_uid</label>
      <input id="uid" placeholder="_uid" name="uid"></input>
    </p>
    <p>
      <label for="token">__client_id</label>
      <input id="token" placeholder="__client_id"></input>
    </p>
  </span>
  <p><input type="checkbox" class="lsCheckbox" name="useAT" id="useAT"></input><label for="useAT" class="lsCheckboxLabel">启用AtCoder</label></p>
  <span id="ATdata">
    <p>
      <label for="uid">REVEL_SESSION</label>
      <input id="uid" placeholder="session" name="session"></input>
    </p>
  </span>
  <button class="setting-confirm">刷新并保存设置</button>
`;
    document.body.appendChild(dialog);
    if(localStorage.uselg=='true') {
        dialog.children[1].children[0].checked=true;
        dialog.children[2].children[0].children[1].value=localStorage.uid;
        dialog.children[2].children[1].children[1].value=localStorage.token;
    }
    if(localStorage.useat=='true') {
        dialog.children[3].children[0].checked=true;
        dialog.children[4].children[0].children[1].value=localStorage.session;
    }
    dialog.children[1].children[0].addEventListener('change',function(){
        dialog.children[2].style.display=(dialog.children[1].children[0].checked?"":"none");
    });
    dialog.children[2].style.display=(dialog.children[1].children[0].checked?"":"none");
    dialog.children[3].children[0].addEventListener('change',function(){
        dialog.children[4].style.display=(dialog.children[3].children[0].checked?"":"none");
    });
    dialog.children[4].style.display=(dialog.children[3].children[0].checked?"":"none");
    dialog.children[5].addEventListener('click',function(){
        if(dialog.children[1].children[0].checked) {
            localStorage.uselg=true;
            localStorage.uid=dialog.children[2].children[0].children[1].value;
            localStorage.token=dialog.children[2].children[1].children[1].value;
        } else {
            localStorage.uselg=false;
        }
        if(dialog.children[3].children[0].checked) {
            localStorage.useat=true;
            localStorage.session=dialog.children[4].children[0].children[1].value;
        } else {
            localStorage.useat=false;
        }
        location.href=location.href;
    });
}
window.addEventListener('message', function(event) {
    if(aborted)	return;
    if (event.origin !== "https://jylh8y-55315.csb.app" || (typeof event.data != "string")) {
        console.log('Denied message from',event.origin);
        return;
    }
    let data=JSON.parse(event.data);
    console.log(data)
    if(data.good=='good') {
        if(alerted)
        {
            location.href=location.href;
        }
        good=true;
        return;
    }
    if(data.text=='-553') {
        if(logging)	return;
        logging=true;
        console.log("Login failed!");
        alert('Your '+data.add.split('.')[2]+' login data is out of date. Please re-login.');
        limesarine_expand();
        return;
    }
    if(data.text=='-553553' && data.add!='test') {
        alert('Request failed! For more data, see the console.');
        return;
    }
    if(data.text=='-553553') {
        return;
    }
    if(data.text=='0') {
        console.log(data.add)
        alert('Failed to get data! For more data, see the console.');
    }
    if(data.text>0 || data.text=='-238315' || data.add.split('.')[2]=='AT') {
        let html='',add=data.add.split('.');
        let label=parseInt(add[0]),pid=add[1];
        if(add[2]=='LG') {
            if(data.text=='-238315') {
                html=`<a href="https://www.luogu.com.cn/problem/${pid}" class='lg-WA'>${pid}</a>`;
            } else {
                html=`<a href="https://www.luogu.com.cn/record/${data.text}" class='lg-AC'>${pid}</a>`
            }
            document.getElementsByClassName('lg-stat')[label].innerHTML=`${html}`
        } else {
            let datas=data.text.split('|');
            html=`<a href="${datas[0]}" class=${datas[1]}>${datas[2]}</a>`
            document.getElementsByClassName('prob-title')[label].innerHTML=document.getElementsByClassName('prob-title')[label].innerHTML.replaceAll(datas[2],html);
        }
        console.log(add,label,pid);
    }
}, false);
function testConnection()
{
    let e=document.createElement('iframe');
    e.src="https://jylh8y-55315.csb.app/?add=test";
    document.body.appendChild(e);
    e.classList.add('lg-frame');
    let img=document.createElement('img');
    img.src="https://jylh8y-55315.csb.app/testimg";
    document.body.appendChild(e);
    e.classList.add('lg-frame');
    img.onload=function(){
        console.log('Image loaded!');
        setTimeout(function(){
            if(!good)
            {
                e.style="position: fixed; height: 100vh; width: 100vw; top: 0; left: 0; z-index: 553553553;";
                setTimeout(function(){
                    alerted=true;
                    alert('Please click the "Yes, proceed to preview" button below.');
                },100);
            }
            else
            {
                document.body.removeChild(e);
                console.log('Connected.');
                deal();
            }
        },1000);
    }
    img.onerror=function(){
        alert('It seems the server has died, please contact smkttl immediately.');
        aborted=true;
    }
}
function getLocalStorage(key,reset) {
    if(aborted)	return;
    if(localStorage[key] && !reset) {
        return localStorage[key];
    }
    alert("Please log in");
    limesarine_expand();
    throw "Please set cookie.";
    return localStorage[key]
}
function sendRequest(pid,add) {
    let e=document.createElement('iframe');
    e.classList.add('lg-frame');
    e.src=`https://jylh8y-55315.csb.app/?uid=${getLocalStorage('uid')}&token=${getLocalStorage('token')}&pid=${pid}&add=${add}&contest=${location.href.split('/').reverse()[0]}`;
    document.body.appendChild(e)
}
function sendRequest2(pid,add) {
    let e=document.createElement('iframe');
    e.classList.add('lg-frame');
    e.src=`https://jylh8y-55315.csb.app/AT?session=${encodeURIComponent(getLocalStorage('session'))}&pid=${pid}&add=${add}&contest=${location.href.split('/').reverse()[0]}`;
    document.body.appendChild(e)
}
function deal()
{
    logging=false;
    let table=document.getElementById('contest-problems');
    if(getLocalStorage('uselg')=='true')
    {
        let header=document.createElement('th');
        header.classList.add('lg-stat');
        header.textContent="洛谷"
        table.children[0].children[0].appendChild(header);
    }
    table=table.children[1]
    let list=JSON.parse(document.getElementsByName('dataJson')[0].value).problems;
    if(getLocalStorage('uselg')=='true')
    {
        for(let i=0;i<list.length;i++)
        {
            let e=document.createElement('td');
            e.classList.add('lg-stat');
            e.textContent="Waiting...";
            table.children[i].appendChild(e);
        }
        for(let i=0;i<list.length;i++)
        {
            if(list[i].oj=='洛谷')
            {
                let num=list[i].probNum;
                sendRequest(num,String(i+1)+'.'+num+'.LG');
            }
            else if(list[i].oj=='AtCoder')
            {
                let num='AT_'+list[i].probNum;
                sendRequest(num,String(i+1)+'.'+num+'.LG');
            }
            else
            {
                document.getElementsByClassName('lg-stat')[i+1].innerHTML=`-`
            }
        }
    }
    if(getLocalStorage('useat')=='true')
    {
        for(let i=0;i<list.length;i++)
        {
            if(list[i].oj=='AtCoder')
            {
                let num=list[i].probNum;
                sendRequest2(num,String(i+1)+'.'+num+'.AT');
                document.getElementsByClassName('prob-title')[i+1].innerHTML+=` (${num})`
            }
        }
    }
}
function injectCSS() {
    let e=document.createElement('style');
    e.innerHTML=`
th.lg-stat {
    width: 120px;
}
td.lg-stat {
    text-align: center;
    width: 100px;
    padding: 6px;
}
.lg-AC {
    color: rgb(82, 196, 26) !important;
}
.lg-frame {
    height: 1px;
    width: 1px;
    overflow: hidden;
}
.lsCheckboxLabel {
    font-size: 150%;
    font-weight: bold;
}
.setting-confirm {
    height: 22.5px;
    border-radius: 5px;
}
`;
    document.body.appendChild(e);
}
function insertLockIcon()
{
    let dialog=document.createElement("div");
    dialog.setAttribute("id","limesarine_lock_icon");
    dialog.style.position="fixed";
    dialog.style.bottom="5px";
    dialog.style.right="5px";
    dialog.style.width="45px";
    dialog.style.height="45px";
    dialog.style.background="#fff";
    dialog.style.borderRadius="8px";
    dialog.style.boxShadow="0 1px 6px rgba(0, 0, 0, .2)";
    dialog.style.borderColor="aliceblue";
    dialog.style.backgroundColor="white";
    dialog.style.fontSize="90%";
    dialog.style.padding="5px";
    dialog.style.justifyContent="center";
    dialog.style.align="center";
    dialog.innerHTML=`
<a unselectable="on" id="limesarine_expand">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35">
    <path d="M31.25 14.75h-2.8c-.2-1-.6-1.9-1.1-2.7l2-2c.6-.6.6-1.5 0-2.1l-2.1-2.1c-.6-.6-1.5-.6-2.1 0l-2 2c-.8-.5-1.7-.9-2.7-1.1v-2.8c0-.8-.7-1.5-1.5-1.5h-3c-.8 0-1.5.7-1.5 1.5v2.8c-1 .2-1.9.6-2.7 1.1l-2-2c-.6-.6-1.5-.6-2.1 0l-2.1 2.1c-.6.6-.6 1.5 0 2.1l2 2c-.5.8-.9 1.7-1.1 2.7h-2.8c-.8 0-1.5.7-1.5 1.5v3c0 .8.7 1.5 1.5 1.5h2.8c.2 1 .6 1.9 1.1 2.7l-2 2c-.6.6-.6 1.5 0 2.1l2.1 2.1c.6.6 1.5.6 2.1 0l2-2c.8.5 1.7.9 2.7 1.1v2.8c0 .8.7 1.5 1.5 1.5h3c.8 0 1.5-.7 1.5-1.5v-2.8c1-.2 1.9-.6 2.7-1.1l2 2c.6.6 1.5.6 2.1 0l2.1-2.1c.6-.6.6-1.5 0-2.1l-2-2c.5-.8.9-1.7 1.1-2.7h2.8c.8 0 1.5-.7 1.5-1.5v-3c0-.8-.7-1.5-1.5-1.5z M17.5 26a8.5 8.5 0 1 1 0-17 8.5 8.5 0 0 1 0 17z" fill="currentColor"/>
  </svg>
</a>
`;
    document.body.appendChild(dialog);
    dialog.addEventListener('click',limesarine_expand);
}
(function() {
    'use strict';

    const observer = new MutationObserver((mutations) => {
        if(document.getElementsByClassName('prob-title').length>1) {
            console.log('Start Processing...');
            injectCSS();
            insertLockIcon();
            observer.disconnect();
            testConnection();
        }
    });
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();