// ==UserScript==
// @name 洛谷通过题目比较器 for fe
// @version 0.2.5
// @description 适用于新版界面的洛谷通过题目比较器
// @author 叶ID (KMnO4y_Fish, yezhiyi9670)
// @match *://www.luogu.com.cn/user/*
// @namespace https://greasyfork.org/zh-CN/users/370663-yezhiyi9670
// @require https://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==
/**
* 比较器原作者是 Anguei.
* 近日洛谷上线了基于 _feInjection 的个人空间,导致原来比较器脚本失效。
* 而原作者较长时间没有更新自己的脚本。这份脚本是重写的,适用于新版界面的比较器。
* 如果设计侵权将删除。
*
* 目前暂不支持在评测记录页面进行比较,稍后将完成这个功能。
*/
(function () {
// 数据接口
var gs = function(name,def='') {
if(localStorage['lg-ac-comparator-s-'+name]) return localStorage['lg-ac-comparator-s-'+name];
return def;
}
var ss = function(name,val) {
localStorage['lg-ac-comparator-s-'+name] = val;
}
var init_settings = function() {
var lst = [
['self','-1'],
['Eaccurate','N'],
['Ecolorize','N'],
['Vcolorize_limit','1500'],
['Egrading','N'],
['Ecount','N'],
];
for(var i = 0; i < lst.length; i++) {
ss(lst[i][0],gs(lst[i][0],lst[i][1]));
}
}
var ps = function(name,str) {
var txt = prompt(str + "\n" + '当前设置:'+gs(name),gs(name));
if(!txt) return;
ss(name,txt);
}
init_settings();
var prompt_settings = function() {
ps('self','你的uid?[整数]');
ps('Eaccurate','是否显示精确通过题数?[Y/N]');
ps('Ecolorize','是否对通过题目列表启用样式?[Y/N]');
ps('Vcolorize_limit','通过大于多少题,则不对通过题目列表染色?[正整数]');
ps('Egrading','是否显示通过数的颜色?[Y/N]');
ps('Ecount','是否显示对方通过而您未通过的数量?[Y/N]');
}
var isYes = function(name) {
return gs(name) == 'Y' || gs(name) == 'y' || gs(name) == 'yes';
}
// 根据用户 AC 数量确定其颜色
// * 这是 洛谷通过题目比较器 - yyfcpp 中一段代码的复印件。
var getGradingColor = function(AcCnt) {
if (AcCnt >= 1275) return "#FF0000";
else if (AcCnt >= 867) return "rgb(255," + ((1275 - AcCnt) / 2) + ",0)";
else if (AcCnt >= 765) return "rgb(" + ((AcCnt - 357) / 2) + "," + ((1275 - AcCnt) / 2) + ",0)";
else if (AcCnt >= 459) return "rgb(" + ((AcCnt - 357) / 2) + ",255,0)";
else if (AcCnt >= 357) return "rgb(51," + ((AcCnt + 51) / 2) + "," + (459 - AcCnt) + ")";
else if (AcCnt >= 204) return "rgb(51," + (AcCnt - 153) + "," + (459 - AcCnt) + ")";
else return "rgb(51,51," + (51 + AcCnt) + ")";
}
// 难度 - 颜色对应表
var getDifficultyColor = function(difficulty) {
if(difficulty == 0) return 'rgb(191, 191, 191)';
if(difficulty == 1) return 'rgb(254, 76, 97)';
if(difficulty == 2) return 'rgb(243, 156, 17)';
if(difficulty == 3) return 'rgb(255, 193, 22)';
if(difficulty == 4) return 'rgb(82, 196, 26)';
if(difficulty == 5) return 'rgb(52, 152, 219)';
if(difficulty == 6) return 'rgb(157, 61, 207)';
if(difficulty == 7) return 'rgb(14, 29, 105)';
}
// 查找并标记 “已通过的题目” 框(暴力算法)
// * 你谷 _feInjection 真毒瘤
var markAcceptedForm = function() {
var arr = $('.lfe-h3');
for(var i=0;i<arr.length;i++) {
if($(arr[i]).html() == '已通过的题目') {
$(arr[i]).parent().addClass('accepted-problem-form');
}
}
};
// 获取数据
var ffflag = false;
var currData = null;
var myData = null;
var myAcMap = {};
var myAttemptedMap = {};
var currAcMap = {};
var noAc=0;
var noAttempt=0;
$.get('?_contentOnly=1',function(e){
currData = e;
$.get('/user/'+gs('self')+'?_contentOnly=1',function(e) {
myData = e;
console.log('用户的数据',currData);
console.log('你的数据',myData);
// ffflag = true;
if(myData['currentData']['passedProblems']) for(var i=0;i<myData['currentData']['passedProblems'].length;i++) {
myAcMap[myData['currentData']['passedProblems'][i]['pid']] = myData['currentData']['passedProblems'][i];
}
if(currData['currentData']['passedProblems']) for(var i=0;i<currData['currentData']['passedProblems'].length;i++) {
currAcMap[currData['currentData']['passedProblems'][i]['pid']] = currData['currentData']['passedProblems'][i];
}
if(myData['currentData']['submittedProblems']) for(var i=0;i<myData['currentData']['submittedProblems'].length;i++) {
myAttemptedMap[myData['currentData']['submittedProblems'][i]['pid']] = myData['currentData']['submittedProblems'][i];
}
if(currData['currentData']['passedProblems']) for(var i=0;i<currData['currentData']['passedProblems'].length;i++) {
var pid = currData['currentData']['passedProblems'][i]['pid'];
if(myAcMap[pid]) {}
else if(myAttemptedMap[pid]) {noAc++;}
else {noAttempt++;noAc++;}
}
console.log('你的通过题目表',myAcMap);
console.log('对方通过题目表',currAcMap);
console.log('你的尝试题目表',myAttemptedMap);
hookInitialized();
})
});
// 顶栏上的精确数字显示
var hook_globalmod = function(){setTimeout(function(){
var $submitbox = $('.stats.normal :nth-child(3) :nth-child(2)');
var $acbox = $('.stats.normal :nth-child(4) :nth-child(2)');
var $rankbox = $('.stats.normal :nth-child(5) :nth-child(2)');
$submitbox .html(currData['currentData']['user']['submittedProblemCount']);
$acbox .html(currData['currentData']['user']['passedProblemCount']);
if(currData['currentData']['user']['ranking'])
$rankbox .html(currData['currentData']['user']['ranking']);
if(isYes('Egrading')) {
$acbox.css('font-weight','400');
$acbox.css('color',getGradingColor(currData['currentData']['user']['passedProblemCount']));
$submitbox.css('font-weight','400');
$submitbox.css('color',getGradingColor(currData['currentData']['user']['submittedProblemCount'] / 3));
if($rankbox.html() != '-') {
$rankbox.css('font-weight','400');
$rankbox.css('color',getGradingColor(150000 / currData['currentData']['user']['ranking']));
}
}
},801)};
// 侧边组件
$('document').ready(function(){setTimeout(function(){
setInterval(function() {
var $sidebar = $('section.side');
var $firstele = $($sidebar.children()[0]);
var $setting = $('.btn.btn-config.lfe-form-sz-middle');
var isMyAccount = ($setting.length != 0);
if($('.add-compare-viewbox').length && !(!ffflag && myData)) return;
if(!ffflag && myData) {
console.log('初始化完成。');
$('.add-compare-viewbox').remove();
ffflag = true;
}
$show_ele = $(`
<div data-v-796309f8 class="card padding-default add-compare-viewbox">
<h3 class="lfe-h3"><svg aria-hidden="true" focusable="false" data-prefix="fad" data-icon="dice-d6" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-dice-d6 fa-w-14" style="color: rgb(52, 152, 219);"><g data-v-d4260d54="" data-v-796309f8="" class="fa-group"><path data-v-d4260d54="" data-v-796309f8="" fill="currentColor" d="M25.87 124.42a8.54 8.54 0 0 1-.06-14.42l166-100.88a61.72 61.72 0 0 1 64.43 0L422.19 110a8.54 8.54 0 0 1-.05 14.47L224 242.55z" class="fa-secondary"></path><path data-v-d4260d54="" data-v-796309f8="" fill="currentColor" d="M0 161.83v197.7c0 23.77 12.11 45.74 31.79 57.7L184 509.71c10.67 6.48 24.05-1.54 24.05-14.44V271.46L12 154.58c-5.36-3.17-12 .85-12 7.25zm436-7.25L240 271.46v223.82c0 12.89 13.39 20.92 24.05 14.43l152.16-92.48c19.68-12 31.79-33.94 31.79-57.7v-197.7c0-6.41-6.64-10.42-12-7.25z" class="fa-primary"></path></g></svg>
通过题目比较器
</h3>
<p style="margin-bottom:-6px;" class="add-compare-infolist">
<span>该用户通过题目</span>
<span data-v-19260819 class="info-content add-compare-uac">-</span>
</p>
<p style="margin-bottom:-6px;" class="add-compare-infolist">
<span>您的通过题目</span>
<span data-v-19260819 class="info-content add-compare-iac">-</span>
</p>
<p style="margin-bottom:-6px;" class="add-compare-infolist">
<span>您尚未通过,对方通过</span>
<span data-v-19260819 class="info-content add-compare-nometoo">-</span>
</p>
<p style="margin-bottom:-6px;" class="add-compare-infolist">
<span>您尚未尝试,对方通过</span>
<span data-v-19260819 class="info-content add-compare-noatt">-</span>
</p>
<button data-v-dc8d06e8="" data-v-4929b25c="" data-v-796309f8="" solid="" class="btn" id="add-compare-setting" style="border-color: rgb(255, 255, 255); color: rgb(255, 255, 255); background-color: rgb(52, 152, 219);margin-top:16px;padding:4px 10px;">修改设置</button>
</div>
<style>
.info-content[data-v-19260819] {
color: rgba(0, 0, 0, 0.45);
float: right;
}
</style>
`);
$show_ele.insertAfter($firstele);
$('#add-compare-setting').click(prompt_settings);
$('.add-compare-infolist').css('display','none');
if(!ffflag) return;
if(isYes('Ecount')) {
$('.add-compare-uac').html('' + currData['currentData']['user']['passedProblemCount']);
$('.add-compare-iac').html('' + myData ['currentData']['user']['passedProblemCount']);
$('.add-compare-nometoo').html('' + noAc);
$('.add-compare-noatt').html('' + noAttempt);
$('.add-compare-infolist').css('display','block');
}
else {
$('.add-compare-infolist').css('display','none');
}
},200);
},801)});
// 列表与难度
$('document').ready(function(){setTimeout(function(){
setInterval(function() {
if(!myData) return;
var $acform = $('.accepted-problem-form');
if(!$acform.length) markAcceptedForm();
$acform = $('.accepted-problem-form');
if(!$acform.length) return;
if(!isYes('Ecolorize') || (gs('Vcolorize_limit') != 0 && gs('Vcolorize_limit') < currData['currentData']['passedProblems'].length)) return;
var arr = $('.accepted-problem-form .problem-id');
if(!arr.length) return;
if($acform.hasClass('accepted-marked') && arr.length > 0 && !$($(arr[0]).children()[0]).hasClass('color-default')) return;
$acform.addClass('accepted-marked');
console.log('正在执行AC列表样式化',$acform);
function markArray(arr) {
for(var i=0;i<arr.length;i++) {
var ele = $(arr[i]);
var pid = ele.children()[0].innerHTML;
var int = $(ele.children()[0]);
int.removeClass('color-default');
// int.css('font-weight','400');
ele.css('font-weight','400');
if(myAcMap[pid]) {
ele.css('background-color','#88FF8833');
}
else if(myAttemptedMap[pid]) {
ele.css('background-color','#FFFF3377');
}
else {
ele.css('background-color','#FFBBBB77');
}
int.css('color',getDifficultyColor(currAcMap[pid]['difficulty']));
int.attr('title',currAcMap[pid]['title']);
if(int.html().length >= 3 && int.html().substr(0,3) == 'UVA') {
int.html('UVa'+int.html().substr(3));
}
}
}
markArray(arr);
},200);
},801)});
// 起始函数
function hookInitialized() {
hook_globalmod();
}
})();