Krunker.io Woobly Wobbly World

Woobly wobbly and disco effect for krunker.io

スクリプトをインストールするには、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         Krunker.io Woobly Wobbly World
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Woobly wobbly and disco effect for krunker.io
// @author       Guava_Thrower
// @match        *://krunker.io/*
// @grant        unsafeWindow
// @grant        GM_addStyle
// ==/UserScript==

GM_addStyle(`
.modal {
    position: absolute;
    left: 50%;
    top: 10px;
    transform: translate(-50%, 0);
    background: #fff;
    z-index: 99999;
    display: flex;
    flex-direction: column;
    font-size: 0.6em;
    padding: 10px;
    background: hsla(0, 100%, 100%, 0.7);
    border-radius: 5px;
    backdrop-filter: blur(2px);
}

.modal label {
    color: rgba(0, 0, 0, 0.6);
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}
`);

(function() {
    'use strict';

    const html = `<div class="modal">
        <label>
            <span>Wobble Strength:</span>
            <input type="range" min="0" max="2" value="0.5" step="0.25" id="effectStrength">
        </label>
        <label>
            <span>Wobble Speed:</span>
            <input type="range" min="0" max="4" value="0.5" step="0.25" id="effectSpeed">
        </label>
        <label>
            <span>Color Speed:</span>
            <input type="range" min="0" max="4" value="0.5" step="0.25" id="colorSpeed">
        </label>
    </div>`;

    const div = document.createElement("div");
    div.innerHTML = html;
    document.body.appendChild(div);

    const Config = {
        effectStrength: 0.5,
        colorSpeed: 0.5,
        effectSpeed: 0.5
    };

    document.getElementById("effectStrength").oninput = function () {
        Config.effectStrength = this.value;
    }

    document.getElementById("colorSpeed").oninput = function () {
        Config.colorSpeed = this.value;
    }

    document.getElementById("effectSpeed").oninput = function () {
        Config.effectSpeed = this.value;
    }

    document.addEventListener("pointerlockchange", function () {
        if (document.pointerLockElement) {
            div.style.display = "none";
        } else {
            div.style.display = "";
        }
    })

    const glPrototype = unsafeWindow.WebGLRenderingContext.prototype;
    const colorData = [];

    glPrototype.getUniformLocation = new Proxy(glPrototype.getUniformLocation, {
        apply(target, thisArgs, args) {
            const result = Reflect.apply(...arguments);
            if (args[1] === "diffuse" && !colorData.find(x => x.program === args[0])) {
                colorData.push({
                    gl: thisArgs,
                    program: args[0],
                    uniformLocation: result
                });
            }
            return result;
        }
    });

    glPrototype.uniform3f = new Proxy(glPrototype.uniform3f, {
        apply(target, thisArgs, args) {
            if (colorData.find(x => x.uniformLocation == args[0])) {
                return;
            }
            return Reflect.apply(...arguments);
        }
    });

    const wobbleData = [];
    let line = "uniform mat4 projectionMatrix;\n";
    let uniformLine = "uniform float time;\n" +
                      "uniform float effectStrength;\n";
    let line2 = "gl_Position = projectionMatrix * mvPosition;";
    let positionLine = "mvPosition.x += cos(time + mvPosition.x) * 0.5 * effectStrength;\n" +
                       "mvPosition.y += sin(time + mvPosition.y) * 3.0 * effectStrength;\n" +
                       "mvPosition.z += sin(time + mvPosition.z) * 0.5 * effectStrength;\n";

    glPrototype.shaderSource = new Proxy(glPrototype.shaderSource, {
        apply(target, gl, args) {
            let srcChanged = false;
            if (gl.getShaderParameter(args[0], gl.SHADER_TYPE) === gl.VERTEX_SHADER && args[1].indexOf(line) > -1) {
                args[1] = args[1].replace(line, line + "\n" + uniformLine);
                args[1] = args[1].replace(line2, positionLine + "\n" + line2);
                srcChanged = true;
            }
            const result = Reflect.apply(...arguments);
            if (srcChanged) {
                wobbleData.push({
                    shader: args[0],
                    program: null,
                    gl: null,
                    uniforms: {},
                });
                console.log("[SCRIPT] Shader found.");
            }
            return result;
        }
    });

    glPrototype.attachShader = new Proxy(glPrototype.attachShader, {
        apply(target, thisArgs, args) {
            let object = wobbleData.find(x => x.shader == args[1]);
            if (object) {
                object.program = args[0];
                console.log("[SCRIPT] Program found!");
            }
            return Reflect.apply(...arguments);
        }
    });

    glPrototype.linkProgram = new Proxy(glPrototype.linkProgram, {
        apply(target, thisArgs, args) {
            let result = Reflect.apply(...arguments);
            let object = wobbleData.find(x => x.program == args[0]);
            if (object) {
                object.gl = thisArgs;
                object.uniforms.time = object.gl.getUniformLocation(object.program, "time");
                object.uniforms.effectStrength = object.gl.getUniformLocation(object.program, "effectStrength");
                console.log("[SCRIPT] Program linked!");
            }
            return result;
        }
    });

    glPrototype.deleteProgram = new Proxy(glPrototype.deleteProgram, {
        apply(target, thisArgs, args) {
            let i1 = colorData.findIndex(x => x.program === args[0]);
            if (i1 > -1) {
                colorData.splice(i1, 1);
            }
            let i2 = wobbleData.findIndex(x => x.program === args[0]);
            if (i2 > -1) {
                wobbleData.splice(i2, 1);
            }
            return Reflect.apply(...arguments);
        }
    });

    let frames = 0;
    let color = [0, 0, 0];

    setInterval(function () {
        frames++;

        // color
        color[0] = Math.sin(frames / 10 * Config.colorSpeed) * 0.5 + 0.5;
        color[1] = -Math.sin(frames / 10 * Config.colorSpeed) * 0.5 + 0.5;
        color[2] = Math.sin(Math.sin(frames / 10 * Config.colorSpeed)) * 0.5 + 0.5;
        colorData.forEach((object) => {
            let { gl, uniformLocation, program } = object;
            let temp = gl.getParameter(gl.CURRENT_PROGRAM);
            gl.useProgram(program);
            gl.uniform3fv(uniformLocation, color);
            gl.useProgram(temp);
        });

        // wobble wobble
        wobbleData.forEach((object) => {
            if (!object.gl) return;
            let { gl, uniforms, program } = object;
            let temp = gl.getParameter(gl.CURRENT_PROGRAM);
            gl.useProgram(program);
            gl.uniform1f(uniforms.time, frames / 100 * Config.effectSpeed);
            gl.uniform1f(uniforms.effectStrength, Config.effectStrength);
            gl.useProgram(temp);
        });
    }, 1000 / 60);
})();