// ==UserScript== // @name Luogu Search AnyWhere // @namespace https://greasyfork.org/users/829530 // @version 0.4.0 // @description Search AnyWhere in Luogu! // @author tiger2005 // @match https://www.luogu.com.cn/* // @icon https://cdn.luogu.com.cn/upload/usericon/3.png // @grant none // @license MIT // @require https://code.jquery.com/jquery-3.6.0.min.js // @downloadURL https://update.greasyfork.icu/scripts/442416/Luogu%20Search%20AnyWhere.user.js // @updateURL https://update.greasyfork.icu/scripts/442416/Luogu%20Search%20AnyWhere.meta.js // ==/UserScript== (function($, undefined) { 'use strict'; $(function() { Date.prototype.pattern = function(format) { let date = { "y+": this.getYear(), "M+": this.getMonth() + 1, "d+": this.getDate(), "h+": this.getHours(), "m+": this.getMinutes(), "s+": this.getSeconds(), "q+": Math.floor((this.getMonth() + 3) / 3), "S+": this.getMilliseconds() }; if (/(y+)/i.test(format)) { format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)); } for (let k in date) { if (new RegExp("(" + k + ")").test(format)) { format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? date[k] : ("00" + date[k]).substr(("" + date[k]).length)); } } return format; }; let settings = localStorage.getItem("lsaw_settings"); if (settings == undefined || settings == 'undefined') settings = {}; else settings = JSON.parse(settings); let majorSettings = [ ["lsawUserDisplay", true], ["lsawProblemDisplay", true], ["lsawOfficialListDisplay", false], ["lsawSelectListDisplay", false], ["lsawProblemDisplayNumber", 50], ["lsawListDisplayNumber", 50], ]; for (let i = 0; i < majorSettings.length; i++) { let key = majorSettings[i][0], val = majorSettings[i][1]; if (settings[key] == undefined || typeof(settings[key]) != typeof(val)) settings[key] = val; } localStorage.setItem("lsaw_settings", JSON.stringify(settings)); $("body").append(`
`); $(".inputArea > input").focus(function() { $(this).parent().addClass("onFocus"); }); $(".inputArea > input").blur(function() { $(this).parent().removeClass("onFocus"); if ($(this).val().length != 0) $(this).parent().addClass("withContent"); else $(this).parent().removeClass("withContent"); }); $(".inputArea").mouseenter(function() { $(this).addClass("onHover"); }); $(".inputArea").mouseleave(function() { $(this).removeClass("onHover"); }); $(".inputAreaSmall > input").focus(function() { $(this).parent().addClass("onFocus"); }); $(".inputAreaSmall > input").blur(function() { $(this).parent().removeClass("onFocus"); if ($(this).val().length != 0) $(this).parent().addClass("withContent"); else $(this).parent().removeClass("withContent"); }); $(".inputAreaSmall").mouseenter(function() { $(this).addClass("onHover"); }); $(".inputAreaSmall").mouseleave(function() { $(this).removeClass("onHover"); }); $(".searchAnywhereClicky").click(function() { let a = $(this).attr("flag"); if (a == "false") { a = true; $(this).attr("flag", a); } else { a = false; $(this).attr("flag", a); } let settingsName = $(this).parent().attr("for"); settings[settingsName] = a; localStorage.setItem("lsaw_settings", JSON.stringify(settings)); }) $(".inputAreaSmall input").change(function() { let a = Number($(this).val()); let settingsName = $(this).parent().parent().parent().attr("for"); settings[settingsName] = a; localStorage.setItem("lsaw_settings", JSON.stringify(settings)); }) $(".searchAnywhereCloseSettings").click(function() { $(".searchAnywhereSettings").css("opacity", "0"); setTimeout(() => { $(".searchAnywhereSettings").css("display", "none"); }, 200); }) $(".searchAnywhereSettingsLink").click(function() { $(".searchAnywhereSettings").css("display", "block"); setTimeout(() => { $(".searchAnywhereSettings").css("opacity", "1"); }, 20); }) const getColorFromPercent = (x, opa) => { let r = 0, g = 0, b = 0; let rr = 231, gg = 76, bb = 60; let rrr = 82, ggg = 196, bbb = 26; // if(x < 0.5){ // r = 255; // g = one * x; // } // else{ // r = 255 - ((x - 0.5) * one); // g = 255; // } r = rr + (rrr - rr) * x; g = gg + (ggg - gg) * x; b = bb + (bbb - bb) * x; r += (60 - r) * (1 - opa); g += (60 - g) * (1 - opa); b += (60 - b) * (1 - opa); r = Math.floor(r); g = Math.floor(g); b = Math.floor(b); return `rgb(${r}, ${g}, ${b})`; }; const problemColors = ["Gray", "Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Black"]; const problemNames = ["暂无评定", "入门", "普及-", "普及/提高-", "普及+/提高", "提高+/省选-", "省选/NOI-", "NOI/NOI+/CTSC"]; let searchTimeout = null; let currentHoverCard = undefined; const changeHoverCard = (x, scroll = true, align = false) => { $(".searchCard.light").removeClass("light"); if (x != undefined && scroll) $(".searchAnywhereMainInput > input").blur(); if (x != undefined) { x.addClass("light").focus(align); if (scroll) { let heg = x[0].offsetTop; let prr = x.parent().parent(); let scr = prr.scrollTop(); let r = heg - x.outerHeight() + 5, l = r - prr.outerHeight() + x.outerHeight() + 10; scr = Math.max(l, Math.min(r, scr)); prr.scrollTop(scr); } } if (scroll) { // remove mouse event $(".searchCard").unbind('mouseenter').unbind('mouseleave'); $(document).mousemove(() => { $(document).unbind('mousemove'); $(".searchCard").unbind('mouseenter').unbind('mouseleave').hover(function() { changeHoverCard($(this), false); }, function() { changeHoverCard(undefined, false); }); }) } currentHoverCard = x; } const searchInfo = () => { searchTimeout = null; let info = $(".inputArea > input").val(); info = $.trim(info); if (info == "") { $(".searchAnywhereContent").html(""); return; } $(".searchAnywhereContent").html(`
加载中……
`); $(".searchAnywhereContent > div").unbind('click').click((event) => { event.stopPropagation(); }) let userHtml = ""; let problemHtml = ""; let officialHtml = ""; let selectHtml = ""; let finishWorks = 0; let networkError = false; let workCnt = (settings.lsawUserDisplay != false) + (settings.lsawProblemDisplay != false) + (settings.lsawOfficialListDisplay != false) + (settings.lsawSelectListDisplay != false); const finishWork = () => { ++finishWorks; if (finishWorks == workCnt) { if (networkError) $(".searchAnywhereContent").html(`
网络错误
`); else if (userHtml == "" && problemHtml == "" && officialHtml == "" && selectHtml == "") $(".searchAnywhereContent").html(`
未搜索到相关内容
`); else { changeHoverCard(undefined, false); $(".searchAnywhereContent").html(`
` + userHtml + problemHtml + officialHtml + selectHtml + `
`); $(".searchAnywhereContent > div").unbind('click').click((event) => { event.stopPropagation(); }) $(".searchCard").unbind('mouseenter').unbind("mouseleave").hover(function() { changeHoverCard($(this), false); }, function() { changeHoverCard(undefined, false); }); } } }; const getProblemStatus = (x, y) => { if (!x && !y) return ``; if (!y) return ``; return ``; } const getCCFLevel = (x) => { if (x == null || x < 3) return ""; let color = ""; if (x <= 5) color = "#5eb95e"; else if (x <= 7) color = "#07a2f1"; else color = "#f1c40f"; return `` } if (settings.lsawUserDisplay != false) $.ajax({ url: `/api/user/search?keyword=${info}`, type: 'GET', success: function(json) { json = json.users; if (json.length != 0 && json[0] != null) { userHtml = `
用户
`; json.forEach((item) => { if (item == null) return; if (item.color == "Cheater") item.badge = "作弊者"; userHtml += `
UID ${item.uid}
${item.name}${getCCFLevel(item.ccfLevel)}${item.badge != null && item.badge != "" ? `
${item.badge}
` : ""}
` }); } finishWork(); }, error: () => { networkError = true; finishWork(); } }); if (settings.lsawProblemDisplay != false) $.ajax({ url: `/problem/list`, type: 'GET', headers: { "x-luogu-type": "content-only", "Accept": "application/json, text/plain, */*", "x-lentille-request": "content-only" }, data: { keyword: info, page: 1, type: "P|B|CF|SP|AT|UVA" }, success: function(json) { if (json.status != 200) { finishWork(); return; } json = json.data.problems; if (json.count != 0) { problemHtml = `
题目查看所有 ${json.count} 道题目
`; for (let i = 0; i < json.result.length && i < settings.lsawProblemDisplayNumber; i++) { let item = json.result[i]; problemHtml += `
${getProblemStatus(item.submitted, item.accepted)}
${item.title}
${item.pid}
${item.totalSubmit}
${item.totalAccepted}
${problemNames[item.difficulty]}
`; }; } finishWork(); }, error: () => { networkError = true; finishWork(); } }); if (settings.lsawOfficialListDisplay != false) $.ajax({ url: `/training/list`, type: "GET", data: { keyword: info, page: 1, type: "official" }, headers: { "x-luogu-type": "content-only" }, success: (json) => { if (json.code != 200) { finishWork(); return; } json = json.currentData; if (json.trainings.result.length != 0) { officialHtml = `
官方题单查看所有 ${json.trainings.count} 份题单
`; for (let i = 0; i < json.trainings.result.length && i < settings.lsawListDisplayNumber; i++) { let item = json.trainings.result[i]; let acs = json.acceptedCounts[item.id]; if (acs == undefined) acs = 0; officialHtml += `
#${item.id}
${item.title}
${acs} / ${item.problemCount}
${item.markCount}
`; } } finishWork(); }, error: () => { networkError = true; finishWork(); } }) if (settings.lsawSelectListDisplay != false) $.ajax({ url: `/training/list`, type: "GET", data: { keyword: info, page: 1, type: "select" }, headers: { "x-luogu-type": "content-only" }, success: (json) => { if (json.code != 200) { finishWork(); return; } json = json.currentData; if (json.trainings.result.length != 0) { selectHtml = `
用户题单查看所有 ${json.trainings.count} 份题单
`; for (let i = 0; i < json.trainings.result.length && i < settings.lsawListDisplayNumber; i++) { let item = json.trainings.result[i]; if (item.provider.color == "Cheater") item.provider.badge = "作弊者"; selectHtml += `
#${item.id}
${item.title}
${item.problemCount}
${(new Date(item.createTime * 1000)).pattern("yyyy/MM/dd")}
${item.markCount}
${item.provider.name} ${getCCFLevel(item.provider.ccfLevel)} ${item.provider.badge != null && item.provider.badge != "" ? `
${item.provider.badge}
` : ""}
`; } } finishWork(); }, error: () => { networkError = true; finishWork(); } }) }; $(".searchAnywhereMainInput > input").unbind('input propertychange').on('input propertychange', function() { if (searchTimeout != null) clearTimeout(searchTimeout); searchTimeout = setTimeout(searchInfo, 1000); }); let searchAnywhereOpen = false; $(".searchAnywhereEntrance").unbind('click').click(function() { if (!searchAnywhereOpen) { $(".searchAnywhere").css("display", "block"); setTimeout(() => { $(".searchAnywhere").css("opacity", "1"); $(".searchAnywhereMainInput > input").focus(); }, 20); } else { $(".searchAnywhere").css("opacity", "0"); setTimeout(() => { $(".searchAnywhere").css("display", "none"); }, 200); } searchAnywhereOpen = !searchAnywhereOpen; }); $(".searchAnywhere").unbind('click').click(() => { $(".searchAnywhere").css("opacity", "0"); setTimeout(() => { $(".searchAnywhere").css("display", "none"); }, 200); searchAnywhereOpen = false; }) $(".searchAnywhereMainInput").unbind('click').click((event) => { event.stopPropagation(); }) $(document).keydown(function(event) { if ((event.keyCode == 186) && (event.ctrlKey || event.metaKey)) { if (!searchAnywhereOpen) { $(".searchAnywhere").css("display", "block"); setTimeout(() => { $(".searchAnywhere").css("opacity", "1"); $(".searchAnywhereMainInput > input").focus(); }, 20); } else { $(".searchAnywhere").css("opacity", "0"); setTimeout(() => { $(".searchAnywhere").css("display", "none"); }, 200); } searchAnywhereOpen = !searchAnywhereOpen; event.preventDefault(); } if (searchAnywhereOpen) { if (event.keyCode == 38) { // Up if (currentHoverCard == undefined) { let lis = $(".searchCard"); if (lis.length == 0) $(".searchAnywhereMainInput > input").focus(); else { currentHoverCard = lis.eq(lis.length - 1); changeHoverCard(currentHoverCard); } } else { currentHoverCard = currentHoverCard.prev(); while (1) { if (currentHoverCard.length == 0 || currentHoverCard.hasClass("searchCard")) break; currentHoverCard = currentHoverCard.prev(); } if (currentHoverCard.length == 0) { $(".searchAnywhereMainInput > input").focus(); currentHoverCard = undefined; } changeHoverCard(currentHoverCard); } event.preventDefault(); } else if (event.keyCode == 40) { // Down if (currentHoverCard == undefined) { let lis = $(".searchCard"); if (lis.length == 0) $(".searchAnywhereMainInput > input").focus(); else { currentHoverCard = lis.eq(0); changeHoverCard(currentHoverCard); } } else { currentHoverCard = currentHoverCard.next(); while (1) { if (currentHoverCard.length == 0 || currentHoverCard.hasClass("searchCard")) break; currentHoverCard = currentHoverCard.next(); } if (currentHoverCard.length == 0) { $(".searchAnywhereMainInput > input").focus(); currentHoverCard = undefined; } changeHoverCard(currentHoverCard); } event.preventDefault(); } else if (event.keyCode == 13) { // Enter if (currentHoverCard != undefined) window.open(currentHoverCard.attr("href"), "_blank"); event.preventDefault(); } else if (event.keyCode == 9) event.preventDefault(); else $(".searchAnywhereMainInput > input").focus(); } }) }); })(window.jQuery.noConflict(true));