您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add encode / decode hex, base64 button for Voz
// ==UserScript== // @name Add Encode / Decode Button for Voz // @namespace 0x4076696e63766e // @version 0.7 // @description Add encode / decode hex, base64 button for Voz // @author 0x4076696e63766e // @match https://voz.vn/t/* // @grant none // @license GPL-3.0 // ==/UserScript== /* * Regex - Decode Script from https://greasyfork.org/en/scripts/504506-decode-hex-strings-on-voz */ (function () { 'use strict'; var $Editor = null; var $BBMode = false; function openDialog(encodeFunc, isDecode) { const input = prompt("Nhập vào văn bản để mã hóa:"); if (input === null) return; // Người dùng đã hủy if(isDecode){ var decoded = null; if(input.match(/\b([0-9A-Fa-f]{2}\s*){4,}\b/g)) decoded = decodeHex(input) if(input.match(/(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})/g)) decoded = decodeBase64(input) openPopup(decoded); return; } const encoded = encodeFunc(input); pickEditor(); if ($Editor) { if($Editor.tagName.toString() === 'DIV'){ $Editor.innerHTML += `<p>${encoded}</p>`; }else{ $Editor.value += `\n${encoded}`; } } } function openPopup(decoded){ const newDiv = document.createElement(`div`); newDiv.className = "overlay-container is-active"; newDiv.innerHTML = ` <div class="overlay" tabindex="-1" role="dialog" aria-hidden="false"> <div class="overlay-title"> <a class="overlay-titleCloser js-overlayClose" role="button" tabindex="0" aria-label="Close"></a> 😤 </div> <div class="overlay-content"> <div class="block-container"> <div class="block-body"> <textarea class="input" style="min-height: 100px; max-height: 602px; padding: 10px 20px 20px; break-word; resize: none; height: 100px;">${decoded}</textarea> </div> </div> </div> </div> ` document.body.appendChild(newDiv); const closeButton = newDiv.querySelector('.js-overlayClose'); closeButton.addEventListener('click', () => { document.body.removeChild(newDiv); }); } function decodeHex(hexString) { hexString = hexString.replace(/\s+/g, ''); if (!/^[0-9A-Fa-f]{2,}$/.test(hexString)) return hexString; let hexStr = ''; try { for (let i = 0; i < hexString.length; i += 2) { hexStr += String.fromCharCode(parseInt(hexString.substr(i, 2), 16)); } if (/^[\x20-\x7E]*$/.test(hexStr) && hexStr.length > 3) { return hexStr; } else { return hexString; } } catch { return hexString; } } function decodeBase64(base64String) { if (!/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(base64String)) return base64String; try { let binaryString = atob(base64String); if (/^[\x20-\x7E]*$/.test(binaryString) && binaryString.length > 3) { return binaryString; } else { return base64String; } } catch { return base64String; } } function hexEncode(str) { return Array.from(str).map(char => char.charCodeAt(0).toString(16).padStart(2, '0')).join(''); } function base64Encode(str) { return btoa(unescape(encodeURIComponent(str))); } function pickEditor() { const editorContainers = document.querySelectorAll('div.message-editorWrapper'); editorContainers.forEach(container => { const textareaEditor = container.querySelector('textarea.input'); const bbEditor = container.querySelector('div.fr-element'); const bbCodeMode = container.querySelector('#xfBbCode-1'); if(bbCodeMode) $BBMode = bbCodeMode.classList.contains('fr-active') $Editor = ($BBMode) ? textareaEditor : bbEditor }); } function createButton(label, callback) { const button = document.createElement('div'); button.className = 'button--primary button'; button.style.marginRight = '5px'; button.textContent = label; button.onclick = callback; return button; } function insertHelper(extraDivs) { if (document.querySelectorAll("div.encode-helper").length > 0) return; extraDivs.forEach(extraDiv => { const newDiv = document.createElement('div'); newDiv.className = 'formButtonGroup encode-helper'; newDiv.appendChild(createButton('Hex', () => openDialog(hexEncode))); newDiv.appendChild(createButton('Base64', () => openDialog(base64Encode))); newDiv.appendChild(createButton('Decode', () => openDialog(null, true))); extraDiv.parentNode.insertBefore(newDiv, extraDiv.nextSibling); }); } function main() { const elements = document.querySelectorAll('div.formButtonGroup'); insertHelper(elements); } function initializeObserver() { new MutationObserver(main).observe(document.documentElement, { childList: true, subtree: true }); } document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', initializeObserver) : initializeObserver(); })();