Hexadecant

Cryptographically secure identification

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Hexadecant
// @namespace    http://tampermonkey.net/
// @version      2026-05-28
// @description  Cryptographically secure identification
// @author       miguel0303
// @match        https://*.ourworldoftext.com/binaryhexadecant
// @match        https://*.ourworldoftext.com/binaryhexadecant/*
// @match        https://twot.fbin.duckdns.org/binaryhexadecant
// @match        https://twot.fbin.duckdns.org/binaryhexadecant/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=ourworldoftext.com
// @grant        none
// ==/UserScript==

/* global w */


(function() {
    'use strict';

    /* ============================================================
       1. Core 4x4 Path Renderer
       ============================================================ */
    function draw4x4Block(ctx, x, y, width, height, mask) {
        const rows = 4;
        const cols = 4;
        const subW = width / cols;
        const subH = height / rows;

        ctx.beginPath();
        for (let i = 0; i < 16; i++) {
            // Check if the i-th bit is set
            if ((mask >> i) & 1) {
                let cx = i % cols;
                let cy = Math.floor(i / rows);
                ctx.rect(x + (cx * subW), y + (cy * subH), subW, subH);
            }
        }
        ctx.fill();
    }

    /* ============================================================
       2. Patching the drawBlockChar Dispatcher
       ============================================================ */
    if (typeof window.drawBlockChar !== 'undefined') {
        const originalDrawBlockChar = window.drawBlockChar;

        window.drawBlockChar = function(char_code, ctx, x, y, width, height) {
            // Range Check: U+C0000 to U+CFFFF
            if (char_code >= 0xC0000 && char_code <= 0xCFFFF) {
                const mask = char_code - 0xC0000;

                // Note: 0xCFFFF results in mask 0xFFFF (all 16 bits),
                // rendering a "full" 4x4 block (solid square).
                draw4x4Block(ctx, x, y, width, height, mask);
                return;
            }

            // Fallback to original renderer for standard blocks
            return originalDrawBlockChar.apply(this, arguments);
        };
    }

    /* ============================================================
       3. Update Validity Check (Required for OWOT to call drawBlockChar)
       ============================================================ */
    if (typeof window.isValidSpecialSymbol !== 'undefined') {
        const originalIsValid = window.isValidSpecialSymbol;
        window.isValidSpecialSymbol = function(char_code) {
            if (char_code >= 0xC0000 && char_code <= 0xCFFFF) {
                return true;
            }
            return originalIsValid(char_code);
        };
    }

    /* ============================================================
       4. Register Chat Command
       ============================================================ */
    if (typeof window.w !== 'undefined' &&
        window.w &&
        window.w.chat &&
        typeof window.w.chat.registerCommand === 'function') {

        window.w.chat.registerCommand("b4", function(args) {
            if (!args || !args[0]) return;

            let input = args[0];
            let val = parseInt(input, 16);

            if (!isNaN(val) && val >= 0 && val <= 0xFFFF) {
                let char = String.fromCodePoint(0xC0000 + val);
                if (typeof window.w.typeChar === 'function') {
                    window.w.typeChar(char);
                }
            }
        }, ["hex"], "Type 4x4 block char", "FFFF");
    }

    /* ============================================================
       5. Settings Cleanup
       ============================================================ */
    if (typeof window.bufferLargeChars !== 'undefined') {
        window.bufferLargeChars = false;
    }

    if (typeof window.w !== 'undefined' && window.w && typeof window.w.redraw === 'function') {
        window.w.redraw();
    }
})();