// ==UserScript== // @name LuoguEmojiSender // @namespace https://github.com/Maxmilite/LuoguEmojiSender // @version 1.4.4 // @description 一款可以帮助您在洛谷轻松发送 QQ 表情信息的插件. // @author Maxmilite // @match https://www.luogu.com.cn/* // @match http://www.luogu.com.cn/* // @grant unsafeWindow // @require https://code.jquery.com/jquery-2.1.1.min.js // @downloadURL https://update.greasyfork.icu/scripts/426868/LuoguEmojiSender.user.js // @updateURL https://update.greasyfork.icu/scripts/426868/LuoguEmojiSender.meta.js // ==/UserScript== (function () { // 这是第一代 LuoguEmojiSender 的最终版本,内容已经相当完善,此后作者将会着力于第二代的开发,第一代基本不会更新。 // 最后更新时间 2021.6.14 // 最后版本 1.4.4 // 第二代目标:实现图形化,近似于 QQ 发送表情 // 作者在这个版本留下了一个臭了的彩蛋 // 1.1 更新内容: // 优化操作逻辑,增加用户配置区 // 1.2 更新内容: // 增加了更多的 QQ 图片,更改了图床 // 1.3 更新内容: // 进一步优化操作逻辑,修复了图片加载的一个BUG,现在可以无忧无虑使用无缝模式了 // 1.3.1 更新内容: // 紧急修复一个由菜刀表情引发的严重BUG // 1.4 更新内容: // 修复了 1.3.1 版本更新日志版本号的bug,修复输入问题,第一代最终版本 // 修复光标漂移问题,修复无缝衔接问题,修复菜刀表情问题,修复若干问题 // 1.4.1 更新内容: // 更换表情源,增加 “替换表情” 按钮,具体详见说明文档 // 1.4.2 更新内容: // 修复一个无缝模式的 bug,添加了部分表情 // 1.4.3 更新内容: // 增加了一个开关自动替换按钮,现在您可以自行决定是否自动替换文中内容了,修复了一个bug,更新了雀魂表情库 // 1.4.4 更新内容: // 增加设置菜单,现在允许对插件进行有关设置了,所有设置将会保存在本地,不会因为版本更新而丢失;增加快速查询表情按钮 var functionIsOn = true, seamlessMode = false, queryIsOn = true; var prefix = "{", suffix = "}"; var userElement = { "样例1": "XXX1.com", "样例2": "XXX2.com", "样例3": "XXX3.com", "样例4": "XXX4.com" }; const replaceElement = { "/ybyb": "", "/wosl": "", "/hs": "", "/psj": "", "/na": "", "/bx": "", "/qdqd": "", "/zy": "", "/nqct": "", "/nzqk": "", "/mjl": "", "/gun": "", "/cb": "", "/my": "", "/mwbq": "", "/kx": "", "/jl": "", "/wyx": "", "/ww": "", "/mdfq": "", "/banzz": "", "/mgx": "", // ----------------- 以上为 1.4.2 更新内容 ----------------- "/aini": "", "/aiq": "", "/am": "", "/azgc": "", "/baiy": "", "/bangbangt": "", "/baojin": "", "/bb": "", "/bkx": "", "/bl": "", "/bobo": "", "/bp": "", "/bq": "", "/bs": "", "/bt": "", "/bu": "", "/bz": "", // "/cd": "", "/cengyiceng": "", "/cg": "", "/ch": "", "/chi": "", "/cj": "", "/cp": "", "/cs": "", "/cy": "", "/dan": "", "/dao": "", "/db": "", "/dg": "", "/dgg": "", "/dk": "", "/dl": "", "/doge": "", "/dx": "", "/dy": "", "/dz": "", "/ee": "", "/emm": "", "/fad": "", "/fade": "", "/fan": "", "/fd": "", "/fendou": "", "/fj": "", "/fn": "", "/fw": "", "/gg": "", "/gy": "", "/gz": "", "/hanx": "", "/haob": "", "/hb": "", "/hc": "", "/hd": "", "/hec": "", "/hhd": "", "/hn": "", "/hp": "", "/hq": "", "/hsh": "", "/ht": "", "/huaix": "", "/hx": "", "/jd": "", "/jh": "", "/jiaybb": "", "/jiaybs": "", "/jie": "", "/jk": "", "/jw": "", "/jx": "", "/jy": "", "/ka": "", "/kb": "", "/kel": "", "/kf": "", "/kg": "", "/kk": "", "/kl": "", "/kt": "", "/kuk": "", "/kun": "", "/kzht": "", "/lb": "", "/lengh": "", "/lh": "", "/ll": "", "/lm": "", "/lq": "", "/lw": "", "/lyj": "", "/meigui": "", "/mm": "", "/ng": "", "/nkt": "", "/oh": "", "/oy": "", "/pch": "", "/pj": "", "/pp": "", "/pt": "", "/px": "", "/qd": "", "/qiang": "", "/qiao": "", "/qq": "", "/qt": "", "/ruo": "", "/sa": "", "/se": "", "/sh": "", "/shd": "", "/shl": "", "/shuai": "", "/shui": "", "/shxi": "", "/sr": "", "/tiao": "", "/tl": "", "/tnl": "", "/tp": "", "/ts": "", "/tsh": "", "/tt": "", "/tuu": "", "/tx": "", "/taiyang": "", "/tyt": "", "/wbk": "", "/whl": "", "/wl": "", "/wn": "", "/wq": "", "/ws": "", "/wul": "", "/wx": "", "/wzm": "", "/xhx": "", "/xia": "", "/xig": "", "/xin": "", "/xjj": "", "/xk": "", "/xs": "", "/xu": "", "/xw": "", "/xy": "", "/xyx": "", "/yao": "", "/yb": "", "/yhh": "", "/yiw": "", "/yl": "", "/youl": "", "/youtj": "", "/yt": "", "/yun": "", "/yx": "", "/zhd": "", "/zhem": "", "/zhh": "", "/zhm": "", "/zhq": "", "/zj": "", "/zk": "", "/zq": "", "/zt": "", "/zuotj": "", "/114514": "[](https://github.com/Maxmilite/LuoguEmojiSender)", "/maj-1!": "", "/maj-2!": "", "/maj-3!": "", "/maj-4!": "", "/maj-5!": "", "/maj-6!": "", "/maj-7!": "", "/maj-8!": "", "/maj-9!": "", "/maj-10!": "", "/maj-11!": "", "/maj-12!": "", "/maj-13!": "", "/maj-14!": "", "/maj-15!": "", "/maj-16!": "", "/maj-17!": "", "/maj-18!": "", "/maj-19!": "", "/maj-20!": "", "/maj-21!": "", "/maj-22!": "", "/maj-23!": "", "/maj-24!": "", "/maj-25!": "", "/maj-26!": "", "/maj-27!": "", "/maj-28!": "", "/maj-29!": "", "/maj-30!": "", "/maj-31!": "", "/maj-32!": "", "/maj-33!": "", "/maj-34!": "", "/maj-35!": "", "/maj-36!": "", "/maj-37!": "", "/maj-38!": "", "/maj-39!": "", "/maj-40!": "", "/maj-41!": "", "/maj-42!": "", "/maj-43!": "", "/maj-44!": "", "/maj-45!": "", "/maj-46!": "", "/maj-47!": "", "/maj-48!": "", "/maj-49!": "", "/maj-50!": "", "/maj-51!": "", "/maj-52!": "", "/maj-53!": "", "/maj-54!": "", "/maj-55!": "", "/maj-56!": "", "/maj-57!": "", "/maj-58!": "", "/maj-59!": "", "/maj-60!": "", "/maj-61!": "", "/maj-62!": "", "/maj-63!": "", "/maj-64!": "", "/maj-65!": "", "/maj-66!": "", "/maj-67!": "", "/maj-68!": "", "/maj-69!": "", "/maj-70!": "", "/maj-71!": "", "/maj-72!": "", "/maj-73!": "", "/maj-74!": "", "/maj-75!": "", "/maj-76!": "", "/maj-77!": "", "/maj-78!": "", "/maj-79!": "", "/maj-80!": "", "/maj-81!": "", "/maj-82!": "", "/maj-83!": "", "/maj-84!": "", "/maj-85!": "", "/maj-86!": "", "/maj-87!": "", "/maj-88!": "", "/maj-89!": "", "/maj-90!": "", "/maj-91!": "", "/maj-92!": "", "/maj-93!": "", "/maj-94!": "", "/maj-95!": "", "/maj-96!": "", "/maj-97!": "", "/maj-98!": "" }; const $ = unsafeWindow.$ || jQuery, markdownPalettes = unsafeWindow.markdownPalettes; function ShowTip(tip, type) { var $tip = $('#tip'); if ($tip.length == 0) { $tip = $(''); $('body').append($tip); } $tip.stop(true).prop('class', 'alert alert-' + type).text(tip).css('margin-left', -$tip.outerWidth() / 2).fadeIn(250).delay(500).fadeOut(250); } function ShowMsg(msg) { ShowTip(msg, 'info'); } function ShowSuccess(msg) { ShowTip(msg, 'success'); } function ShowFailure(msg) { ShowTip(msg, 'danger'); } function ShowWarn(msg, $focus, clear) { ShowTip(msg, 'warning'); if ($focus) { $focus.focus(); if (clear) $focus.val(''); } return false; } function getSubString(sourceString = "", findPos = -1) { if (findPos == -1) { return "zr.tk"; } if (findPos <= 5) { return ""; } let resultString = ""; for (let i = findPos - 5; i < findPos; i++) { resultString += sourceString[i]; } // if (resultString == "tps:/") { // return "9zr.tk"; // } return resultString; } function sliceString(sourceString = "", leftSide = 0, rightSide = 0) { let resultString = "" for (let i = leftSide; i <= rightSide; i++) { resultString += sourceString[i]; } return resultString; } function replaceString(stringToChange = "") { let isChanged = false; for (let i in replaceElement) { let changedStr = prefix + i + suffix; while (getSubString(stringToChange, stringToChange.lastIndexOf(changedStr)) != "zr.tk" && getSubString(stringToChange, stringToChange.lastIndexOf(changedStr)) != "jsoul") { // console.log(getSubString(stringToChange, stringToChange.lastIndexOf(changedStr))) isChanged = true; // stringToChange = stringToChange.replace(changedStr, replaceElement[i]); stringToChange = sliceString(stringToChange, 0, stringToChange.lastIndexOf(changedStr) - 1) + replaceElement[i] + sliceString(stringToChange, stringToChange.lastIndexOf(changedStr) + changedStr.length, stringToChange.length - 1); } } for (let i in userElement) { let changedStr = prefix + i + suffix; while (getSubString(stringToChange, stringToChange.lastIndexOf(changedStr)) != "zr.tk" && getSubString(stringToChange, stringToChange.lastIndexOf(changedStr)) != "jsoul") { isChanged = true; // stringToChange = stringToChange.replace(changedStr, userElement[i]); stringToChange = sliceString(stringToChange, 0, stringToChange.lastIndexOf(changedStr) - 1) + userElement[i] + sliceString(stringToChange, stringToChange.lastIndexOf(changedStr) + changedStr.length, stringToChange.length - 1); } } if (isChanged == true) { return stringToChange; } else { return undefined; } } function main() { if (functionIsOn == false) { return; } if (typeof markdownPalettes != "undefined") { let changedStr = replaceString($(".CodeMirror-wrap textarea").val()); if (changedStr != undefined) { $(".CodeMirror-wrap textarea").val(changedStr); $(".CodeMirror-wrap textarea").trigger("input"); } } if (document.getElementById("feed-content") != null) { let changedStr = replaceString(document.getElementById("feed-content").value); if (changedStr != undefined) { document.getElementById("feed-content").value = changedStr; } } } function replaceAll() { if (replaceString(markdownPalettes.content) != undefined) { markdownPalettes.content = replaceString(markdownPalettes.content); ShowSuccess("文中所有表情已手动替换"); return; } else { return; } } function writeConfig() { lsSet("LuoguEmojiSenderPrefix", prefix); lsSet("LuoguEmojiSenderSuffix", suffix); lsSet("LuoguEmojiSenderIsOn", JSON.stringify(functionIsOn)); lsSet("LuoguEmojiSenderIsSeamless", JSON.stringify(seamlessMode)); lsSet("LuoguEmojiSenderQueryIsOn", JSON.stringify(queryIsOn)); lsSet("LuoguEmojiSenderUserElements", JSON.stringify(userElement, null, 4)); } function readConfig() { prefix = lsGet("LuoguEmojiSenderPrefix"); suffix = lsGet("LuoguEmojiSenderSuffix"); functionIsOn = JSON.parse(lsGet("LuoguEmojiSenderIsOn")); seamlessMode = JSON.parse(lsGet("LuoguEmojiSenderIsSeamless")); queryIsOn = JSON.parse(lsGet("LuoguEmojiSenderQueryIsOn")); if (seamlessMode == true) { prefix = "", suffix = ""; } userElement = JSON.parse(lsGet("LuoguEmojiSenderUserElements")); } function lsGet(x = "") { return unsafeWindow.localStorage.getItem(x); } function lsSet(x = "", content = "") { unsafeWindow.localStorage.setItem(x, content); } var setting = new Object; setting.openSetting = function () { $("#lesSettingDiv").slideToggle(); if (seamlessMode == true) { document.getElementsByName("seamless")[0].click(); } else { document.getElementsByName("seamless")[1].click(); } if (queryIsOn == true) { document.getElementsByName("query")[0].click(); } else { document.getElementsByName("query")[1].click(); } } setting.cancelSetting = function () { if (confirm("当前设置未保存,确认取消?") == true) { location.reload(); } } setting.saveSetting = function () { if (confirm("确认保存当前设置?") == true) { seamlessMode = $("[name='seamless']")[0].checked; userElement = JSON.parse($("#userElementBox")[0].value); prefix = $("[name='prefix']")[0].value; suffix = $("[name='suffix']")[0].value; queryIsOn = $("[name='query']")[0].checked; writeConfig(); alert("保存成功"); location.reload(); } } function init() { $(`
插件设置
LuoguEmojiSender 设置
>