Greasy Fork

Greasy Fork is available in English.

洛谷通过题目比较器 for fe

适用于新版界面的洛谷通过题目比较器

当前为 2019-11-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         洛谷通过题目比较器 for fe
// @version      0.2.3
// @description  适用于新版界面的洛谷通过题目比较器
// @author       叶ID (KMnO4y_Fish, yezhiyi9670)
// @match        *://www.luogu.org/user/*
// @namespace    http://greasyfork.icu/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;
      for(var i=0;i<myData['currentData']['passedProblems'].length;i++) {
        myAcMap[myData['currentData']['passedProblems'][i]['pid']] = myData['currentData']['passedProblems'][i];
      }
      for(var i=0;i<currData['currentData']['passedProblems'].length;i++) {
        currAcMap[currData['currentData']['passedProblems'][i]['pid']] = currData['currentData']['passedProblems'][i];
      }
      for(var i=0;i<myData['currentData']['submittedProblems'].length;i++) {
        myAttemptedMap[myData['currentData']['submittedProblems'][i]['pid']] = myData['currentData']['submittedProblems'][i];
      }
      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','700');
      $acbox.css('color',getGradingColor(currData['currentData']['user']['passedProblemCount']));
      $submitbox.css('font-weight','700');
      $submitbox.css('color',getGradingColor(currData['currentData']['user']['submittedProblemCount'] / 3));
      if($rankbox.html() != '-') {
        $rankbox.css('font-weight','700');
        $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>
            &nbsp;
            通过题目比较器
          </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','700');
          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('UV'+int.html().substr(3));
          }
        }
      }
      
      markArray(arr);
    },200);     
  },801)});
  
  // 起始函数
  function hookInitialized() {
    hook_globalmod();
  }
})();