Kuro’s Helper

Pink UI + stronger face attachment for Omoggle

2026/06/02のページです。最新版はこちら

スクリプトをインストールするには、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         Kuro’s Helper
// @namespace    http://tampermonkey.net/
// @version      5.1
// @description  Pink UI + stronger face attachment for Omoggle
// @author       Grok
// @match        *://omoggle.com/*
// @match        *://*.omoggle.com/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';
    if (window.__kuroHelperLoaded) return;
    window.__kuroHelperLoaded = true;

    let active = true;
    let jitterAmount = 0.18;
    let jawSharpness = 8.5;

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { alpha: false });
    canvas.width = 640;
    canvas.height = 480;

    const faceConfig = {
        eyeTilt: 22,
        eyeWidth: 27,
        eyeHeight: 9,
        eyeSpacing: 53,
        faceWidth: 88,
        faceHeight: 615,
        jawWidth: 74,
        jawDepth: 214,
        mouthY: 46,
        philtrumY: 17,
        headX: 0,
        headY: 0,
        rotateZ: 0,
        rotateX: 0,
        rotateY: 0,
    };

    function updateJaw() {
        const f = jawSharpness / 10;
        faceConfig.jawWidth = 71 + f * 12;
        faceConfig.jawDepth = 198 + f * 58;
    }
    updateJaw();

    function rotatePoint3D(x, y, z, rx, ry, rz) {
        let x1 = x * Math.cos(rz) - y * Math.sin(rz);
        let y1 = x * Math.sin(rz) + y * Math.cos(rz);
        let y2 = y1 * Math.cos(rx) - z * Math.sin(rx);
        let z2 = y1 * Math.sin(rx) + z * Math.cos(rx);
        let x3 = x1 * Math.cos(ry) + z2 * Math.sin(ry);
        let z3 = -x1 * Math.sin(ry) + z2 * Math.cos(ry);
        return {x: x3, y: y2, z: z3};
    }

    function project(x, y, z, focal = 620) {
        const scale = focal / (focal + z);
        return {x: x * scale, y: y * scale, scale};
    }

    function renderFace(targetCtx, W, H, config, jitter) {
        targetCtx.clearRect(0, 0, W, H);
        targetCtx.fillStyle = "#0a0a0a";
        targetCtx.fillRect(0, 0, W, H);

        const t = Date.now() * 0.016;
        const jx = Math.sin(t) * jitter;
        const jy = Math.cos(t * 1.15) * (jitter * 0.6);

        const baseCX = 320 + config.headX * 75 + jx;
        const baseCY = 218 + config.headY * 75 + jy;

        const rx = config.rotateX * Math.PI / 180;
        const ry = config.rotateY * Math.PI / 180;
        const rz = config.rotateZ * Math.PI / 180;

        function tp(dx, dy, dz = 0) {
            const r = rotatePoint3D(dx, dy, dz, rx, ry, rz);
            const p = project(r.x, r.y, r.z);
            return {x: baseCX + p.x, y: baseCY + p.y, s: p.scale};
        }

        targetCtx.save();
        targetCtx.translate(W/2, H/2);
        targetCtx.scale(Math.min(W/640, H/480), Math.min(W/640, H/480));
        targetCtx.translate(-320, -240);

        // Head
        targetCtx.beginPath();
        for (let i = 0; i <= 50; i++) {
            const a = (i / 50) * Math.PI * 2;
            const p = tp(Math.cos(a) * config.faceWidth, Math.sin(a) * config.faceHeight + 15);
            i === 0 ? targetCtx.moveTo(p.x, p.y) : targetCtx.lineTo(p.x, p.y);
        }
        targetCtx.closePath();

        const grad = targetCtx.createRadialGradient(baseCX-15, baseCY-25, 30, baseCX, baseCY+40, 190);
        grad.addColorStop(0, "#f8c4d8");
        grad.addColorStop(0.7, "#c15a8a");
        grad.addColorStop(1, "#2a0f1f");
        targetCtx.fillStyle = grad;
        targetCtx.fill();

        // Eyes
        [-1, 1].forEach(side => {
            const ep = tp(config.eyeSpacing * side, -18);
            targetCtx.save();
            targetCtx.translate(ep.x, ep.y);
            targetCtx.rotate((side * config.eyeTilt) * Math.PI / 180);
            targetCtx.scale(ep.s, ep.s);
            targetCtx.fillStyle = "#111";
            targetCtx.fillRect(-config.eyeWidth/2, -config.eyeHeight/2, config.eyeWidth, config.eyeHeight);
            targetCtx.restore();
        });

        // Philtrum + Mouth + Jaw
        const pp = tp(0, config.philtrumY);
        targetCtx.fillStyle = "#111";
        targetCtx.beginPath();
        targetCtx.arc(pp.x, pp.y, 7.5 * pp.s, 0, Math.PI*2);
        targetCtx.fill();

        const mL = tp(-29, config.mouthY);
        const mR = tp(29, config.mouthY);
        const mC = tp(0, config.mouthY - 4);
        targetCtx.strokeStyle = "#111";
        targetCtx.lineWidth = 6.5;
        targetCtx.beginPath();
        targetCtx.moveTo(mL.x, mL.y);
        targetCtx.quadraticCurveTo(mC.x, mC.y, mR.x, mR.y);
        targetCtx.stroke();

        // Jaw
        const jL = tp(-config.jawWidth, config.mouthY);
        const jR = tp(config.jawWidth, config.mouthY);
        const bottom = 44 - (jawSharpness * 2.6);
        const jCL = tp(-bottom, config.jawDepth);
        const jCR = tp(bottom, config.jawDepth);

        targetCtx.lineWidth = 15;
        targetCtx.lineJoin = "round";
        targetCtx.beginPath();
        targetCtx.moveTo(jL.x, jL.y);
        targetCtx.lineTo(jCL.x, jCL.y);
        targetCtx.lineTo(jCR.x, jCR.y);
        targetCtx.lineTo(jR.x, jR.y);
        targetCtx.stroke();

        targetCtx.restore();
    }

    function drawPerfectFace() {
        renderFace(ctx, 640, 480, faceConfig, jitterAmount);
    }

    // Stronger Hook
    function hookWebGL() {
        const hook = (proto) => {
            if (!proto || proto._kuroHooked) return;
            proto._kuroHooked = true;
            const orig = proto.texImage2D;
            proto.texImage2D = function (...args) {
                if (active && args[args.length-1] instanceof HTMLVideoElement) {
                    drawPerfectFace();
                    args[args.length-1] = canvas;
                }
                return orig.apply(this, args);
            };
        };

        if (window.WebGLRenderingContext) hook(window.WebGLRenderingContext.prototype);
        if (window.WebGL2RenderingContext) hook(window.WebGL2RenderingContext.prototype);
    }

    hookWebGL();

    // =============== PINK UI ===============
    function injectUI() {
        if (document.getElementById('kuro-ui')) return;

        const ui = document.createElement('div');
        ui.id = 'kuro-ui';
        ui.innerHTML = `
            <div id="kuro-window">
                <div id="kuro-header">
                    <span>🌸 Kuro’s Helper</span>
                    <button id="kuro-minimize">_</button>
                </div>
                <div id="kuro-body">
                    <button id="kuro-toggle">Deactivate</button>

                    <div class="slider-row">
                        <label>Jitter <span id="v-jit">0.18</span></label>
                        <input type="range" id="k-jitter" min="0" max="1.5" step="0.01" value="0.18">
                    </div>
                    <div class="slider-row">
                        <label>Eye Tilt <span id="v-tilt">22</span></label>
                        <input type="range" id="k-tilt" min="0" max="45" step="1" value="22">
                    </div>
                    <div class="slider-row">
                        <label>Jaw Sharpness <span id="v-sharp">8.5</span>/10</label>
                        <input type="range" id="k-sharp" min="0" max="10" step="0.1" value="8.5">
                    </div>

                    <canvas id="kuro-preview"></canvas>
                </div>
            </div>
        `;

        const css = document.createElement('style');
        css.textContent = `
            #kuro-window {
                position: fixed; top: 15px; left: 15px; width: 290px;
                background: rgba(255, 105, 180, 0.92);
                border: 3px solid #ff69b4;
                border-radius: 18px;
                color: white;
                font-family: Arial, sans-serif;
                box-shadow: 0 0 35px rgba(255, 20, 147, 0.6);
                z-index: 2147483647;
                overflow: hidden;
            }
            #kuro-header {
                background: #db277f;
                padding: 10px 14px;
                font-weight: bold;
                display: flex;
                justify-content: space-between;
                cursor: move;
            }
            #kuro-body { padding: 14px; }
            button {
                width: 100%; padding: 13px; margin: 8px 0;
                border: none; border-radius: 12px;
                background: #ff1493; color: white;
                font-weight: bold; cursor: pointer;
            }
            .slider-row { margin: 14px 0; }
            .slider-row label { display: block; margin-bottom: 4px; font-size: 14px; }
            input[type=range] { width: 100%; accent-color: #ff69b4; }
            #kuro-preview { width: 100%; height: 165px; background: #000; border-radius: 12px; margin-top: 8px; }
        `;
        document.head.appendChild(css);
        document.body.appendChild(ui);

        // Preview
        const prev = document.getElementById('kuro-preview');
        const pctx = prev.getContext('2d');
        prev.width = 320; prev.height = 180;

        function loop() {
            drawPerfectFace();
            pctx.drawImage(canvas, 0, 0, 320, 180);
            requestAnimationFrame(loop);
        }
        loop();

        // Controls
        document.getElementById('kuro-toggle').onclick = () => {
            active = !active;
            this.textContent = active ? "Deactivate" : "Activate";
        };

        document.getElementById('k-jitter').oninput = e => {
            jitterAmount = +e.target.value;
            document.getElementById('v-jit').textContent = jitterAmount.toFixed(2);
        };
        document.getElementById('k-tilt').oninput = e => {
            faceConfig.eyeTilt = +e.target.value;
            document.getElementById('v-tilt').textContent = faceConfig.eyeTilt;
        };
        document.getElementById('k-sharp').oninput = e => {
            jawSharpness = +e.target.value;
            document.getElementById('v-sharp').textContent = jawSharpness.toFixed(1);
            updateJaw();
        };

        document.getElementById('kuro-minimize').onclick = () => {
            const body = document.getElementById('kuro-body');
            body.style.display = body.style.display === 'none' ? 'block' : 'none';
        };

        // Draggable
        const win = document.getElementById('kuro-window');
        const hdr = document.getElementById('kuro-header');
        let dragging = false, ox, oy;

        hdr.onmousedown = e => {
            dragging = true;
            ox = e.clientX - win.offsetLeft;
            oy = e.clientY - win.offsetTop;
        };
        document.onmousemove = e => {
            if (dragging) {
                win.style.left = (e.clientX - ox) + 'px';
                win.style.top = (e.clientY - oy) + 'px';
            }
        };
        document.onmouseup = () => dragging = false;
    }

    // Aggressive UI injection
    const uiInterval = setInterval(() => {
        if (document.body) injectUI();
    }, 800);

    // Also try on mutations
    new MutationObserver(() => injectUI()).observe(document.documentElement, { childList: true, subtree: true });
})();