Minefun FPS & CPS Counter, Key Display,CPS Graph,Reload & FPS Alert & Crosshair

minefun.ioでFPSとCPS、過去5秒のCPS線グラフ、押されているキー表示、リロード、FPS低下アラート、照準を追加

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         Minefun FPS & CPS Counter, Key Display,CPS Graph,Reload & FPS Alert & Crosshair
// @namespace    https://minefun.io/
// @license MIT
// @icon         data:image/webp;base64,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
// @version      1.9.9.1
// @description  minefun.ioでFPSとCPS、過去5秒のCPS線グラフ、押されているキー表示、リロード、FPS低下アラート、照準を追加
// @match        *://minefun.io/*
// @grant        none
// ==/UserScript==

(function() {

    'use strict';



    // スタイル定義

    const styles = `

        #mfCounterContainer {

            position: fixed;

            top: 10px;

            left: 10px;

            background-color: rgba(30, 30, 30, 0.8);

            color: #eee;

            padding: 10px;

            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;

            font-size: 14px;

            z-index: 1000;

            cursor: grab;

            border-radius: 5px;

            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);

            display: flex;

            flex-direction: column;

            align-items: flex-start;

            gap: 8px;

        }

        #mfCounterText {

            white-space: pre-line;

        }

        #mfKeyDisplay {

            display: flex;

            gap: 5px;

            margin-top: 5px;

        }

        .key-icon {

            background-color: #444;

            color: #eee;

            padding: 5px;

            border-radius: 3px;

            font-size: 12px;

            min-width: 20px;

            text-align: center;

        }

        #mfImageContainer {

            position: relative;

            width: 40px;

            height: 40px;

            border-radius: 50%;

            overflow: hidden;

            border: 1px solid #555;

            display: flex;

            justify-content: center;

            align-items: center;

        }

        #mfImage {

            width: 100%;

            height: 100%;

            object-fit: cover;

        }

        #mfReloadButton {

            background-color: #555;

            color: #eee;

            border: none;

            padding: 6px 10px;

            border-radius: 5px;

            font-size: 12px;

            cursor: pointer;

            transition: background-color 0.3s ease;

            margin-top: 5px;

        }

        #mfReloadButton:hover {

            background-color: #777;

        }

        #mfFpsAlert {

            background-color: rgba(255, 0, 0, 0.7);

            color: white;

            padding: 5px;

            border-radius: 5px;

            font-size: 12px;

            margin-top: 5px;

        }

        .switch-container {

            display: flex;

            align-items: center;

            gap: 8px;

            margin-top: 5px;

        }

        .switch {

            position: relative;

            display: inline-block;

            width: 40px;

            height: 20px;

        }

        .switch input {

            opacity: 0;

            width: 0;

            height: 0;

        }

        .slider {

            position: absolute;

            cursor: pointer;

            top: 0;

            left: 0;

            right: 0;

            bottom: 0;

            background-color: #ccc;

            transition: .4s;

            border-radius: 20px;

        }

        .slider:before {

            position: absolute;

            content: "";

            height: 16px;

            width: 16px;

            left: 2px;

            bottom: 2px;

            background-color: white;

            transition: .4s;

            border-radius: 50%;

        }

        input:checked + .slider {

            background-color: #2196F3;

        }

        input:focus + .slider {

            box-shadow: 0 0 1px #2196F3;

        }

        input:checked + .slider:before {

            transform: translateX(20px);

        }

        .switch-label {

            font-size: 12px;

            color: #ccc;

        }

        #mfCrosshair {

            position: fixed;

            top: 50%;

            left: 50%;

            transform: translate(-50%, -50%);

            width: 20px;

            height: 20px;

            border: 1px solid rgba(255, 255, 255, 0.5);

            border-radius: 50%;

            z-index: 9999;

            display: none; /* 初期状態は非表示 */

            pointer-events: none; /* クリックを透過 */

        }

        #mfCrosshair:before, #mfCrosshair:after {

            content: '';

            position: absolute;

            background-color: rgba(255, 255, 255, 0.5);

        }

        #mfCrosshair:before {

            left: 50%;

            top: 2px;

            bottom: 2px;

            width: 1px;

            transform: translateX(-50%);

        }

        #mfCrosshair:after {

            top: 50%;

            left: 2px;

            right: 2px;

            height: 1px;

            transform: translateY(-50%);

        }

        #mfCpsGraph {

            width: 100px;

            height: 30px;

            margin-top: 5px;

            border: 1px solid #555;

            border-radius: 3px;

            background-color: #333;

        }

    `;



    const styleSheet = document.createElement("style");

    styleSheet.type = "text/css";

    styleSheet.innerText = styles;

    document.head.appendChild(styleSheet);



    // コンテナ要素の作成

    const counterContainer = document.createElement('div');

    counterContainer.id = 'mfCounterContainer';

    document.body.appendChild(counterContainer);



    // テキスト要素の作成

    const textElement = document.createElement('span');

    textElement.id = 'mfCounterText';

    counterContainer.appendChild(textElement);



    // キー表示コンテナの作成

    const keyDisplayContainer = document.createElement('div');

    keyDisplayContainer.id = 'mfKeyDisplay';

    counterContainer.appendChild(keyDisplayContainer);



    // CPSグラフ表示用のキャンバス要素を作成

    const cpsGraphCanvas = document.createElement('canvas');

    cpsGraphCanvas.id = 'mfCpsGraph';

    counterContainer.appendChild(cpsGraphCanvas);

    const cpsGraphCtx = cpsGraphCanvas.getContext('2d');

    const cpsHistory = [];

    const maxCpsHistoryLength = 5; // 過去5秒



    // 画像要素の作成

    const imageContainer = document.createElement('div');

    imageContainer.id = 'mfImageContainer';

    counterContainer.appendChild(imageContainer);



    const imageElement = document.createElement('img');

    imageElement.id = 'mfImage';

    imageElement.src = 'https://cdn.minefun.io/users/67629a12aa9a815752742647/27EY08XPCCCXH.webp';

    imageContainer.appendChild(imageElement);



    // スーパーリロードボタンの作成

    const reloadButton = document.createElement('button');

    reloadButton.id = 'mfReloadButton';

    reloadButton.textContent = 'Reload';

    reloadButton.addEventListener('click', () => {

        window.location.reload(true); // 強制リロード

    });

    counterContainer.appendChild(reloadButton);



    // FPS低下アラート表示要素

    const fpsAlertElement = document.createElement('div');

    fpsAlertElement.id = 'mfFpsAlert';

    fpsAlertElement.style.display = 'none'; // 初期状態は非表示

    counterContainer.appendChild(fpsAlertElement);



    // 照準表示のコンテナ

    const crosshairSwitchContainer = document.createElement('div');

    crosshairSwitchContainer.classList.add('switch-container');

    counterContainer.appendChild(crosshairSwitchContainer);



    // 照準表示のトグルスイッチ

    const crosshairLabel = document.createElement('label');

    crosshairLabel.classList.add('switch');

    crosshairSwitchContainer.appendChild(crosshairLabel);



    const crosshairToggle = document.createElement('input');

    crosshairToggle.type = 'checkbox';

    crosshairLabel.appendChild(crosshairToggle);



    const crosshairSlider = document.createElement('span');

    crosshairSlider.classList.add('slider');

    crosshairLabel.appendChild(crosshairSlider);



    const crosshairSwitchLabel = document.createElement('span');

    crosshairSwitchLabel.classList.add('switch-label');

    crosshairSwitchLabel.textContent = 'Crosshair';

    crosshairSwitchContainer.appendChild(crosshairSwitchLabel);



    // 照準要素の作成

    const crosshairElement = document.createElement('div');

    crosshairElement.id = 'mfCrosshair';

    document.body.appendChild(crosshairElement);



    // FPS計測

    let fps = 0;

    let lastFPSTime = performance.now();

    let frameCount = 0;



    function updateFPS(currentTime) {

        frameCount++;

        const deltaTime = currentTime - lastFPSTime;



        if (deltaTime >= 100) {

            fps = Math.round((frameCount * 1000) / deltaTime * 10) / 10;

            frameCount = 0;

            lastFPSTime = currentTime;



            // FPS低下アラートの表示/非表示

            if (fps < 30) {

                fpsAlertElement.textContent = `FPSが${fps}です`;

                fpsAlertElement.style.display = 'block';

            } else {

                fpsAlertElement.style.display = 'none';

            }

        }



        requestAnimationFrame(updateFPS);

    }



    requestAnimationFrame(updateFPS);



    // CPS計測と履歴の更新

    let cps = 0;

    let clickCount = 0;

    let lastCPSTime = performance.now();



    document.addEventListener('mousedown', () => {

        clickCount++;

    });



    function updateCPS() {

        const currentTime = performance.now();

        const deltaTime = currentTime - lastCPSTime;



        if (deltaTime >= 1000) {

            cps = clickCount;

            clickCount = 0;

            lastCPSTime = currentTime;



            cpsHistory.push(cps);

            if (cpsHistory.length > maxCpsHistoryLength) {

                cpsHistory.shift(); // 古いデータを削除

            }

        }

        requestAnimationFrame(updateCPS);

    }



    requestAnimationFrame(updateCPS);



    // CPSグラフの描画 (線グラフ)

    function drawCpsGraph() {

        cpsGraphCtx.clearRect(0, 0, cpsGraphCanvas.width, cpsGraphCanvas.height);

        if (cpsHistory.length > 1) {

            cpsGraphCtx.strokeStyle = '#00ff00'; // 線の色

            cpsGraphCtx.lineWidth = 2;

            cpsGraphCtx.beginPath();



            const maxCps = Math.max(...cpsHistory, 1); // 最小値を1として0除算を防ぐ

            const xIncrement = cpsGraphCanvas.width / (cpsHistory.length - 1);



            cpsHistory.forEach((cpsValue, index) => {

                const x = index * xIncrement;

                const y = cpsGraphCanvas.height - (cpsValue / maxCps) * cpsGraphCanvas.height;



                if (index === 0) {

                    cpsGraphCtx.moveTo(x, y);

                } else {

                    cpsGraphCtx.lineTo(x, y);

                }

            });



            cpsGraphCtx.stroke();

        }

        requestAnimationFrame(drawCpsGraph);

    }



    requestAnimationFrame(drawCpsGraph);



    // 押されているキーの表示 (アイコン)

    const pressedKeys = new Set();

    const keyIconMap = {

        'w': 'W', 'a': 'A', 's': 'S', 'd': 'D',

        ' ': 'Space', 'shift': 'Shift', 'ctrl': 'Ctrl', 'alt': 'Alt',

        'tab': 'Tab', 'capslock': 'Caps', 'enter': 'Enter',

        'arrowup': '↑', 'arrowdown': '↓', 'arrowleft': '←', 'arrowright': '→',

        'escape': 'Esc',

        '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '0': '0',

        '`': '`', '-': '-', '=': '=', '[': '[', ']': ']', '\\': '\\',

        ';': ';', '\'': '\'', ',': ',', '.': '.', '/': '/',

        'f1': 'F1', 'f2': 'F2', 'f3': 'F3', 'f4': 'F4', 'f5': 'F5', 'f6': 'F6',

        'f7': 'F7', 'f8': 'F8', 'f9': 'F9', 'f10': 'F10', 'f11': 'F11', 'f12': 'F12'

        // 必要に応じて他のキーも追加

    };



    document.addEventListener('keydown', (event) => {

        pressedKeys.add(event.key.toLowerCase());

        updateKeyDisplay();

    });



    document.addEventListener('keyup', (event) => {

        pressedKeys.delete(event.key.toLowerCase());

        updateKeyDisplay();

    });



    function updateKeyDisplay() {

        keyDisplayContainer.innerHTML = ''; // Clear previous icons

        pressedKeys.forEach(key => {

            const iconText = keyIconMap[key] || key.toUpperCase(); // マップにない場合は大文字で表示

            const keyIcon = document.createElement('div');

            keyIcon.classList.add('key-icon');

            keyIcon.textContent = iconText;

            keyDisplayContainer.appendChild(keyIcon);

        });

    }



    // 表示の更新

    function updateDisplay() {

        textElement.textContent = `FPS: ${fps}\nCPS: ${cps}\nBy kutu524_`;

        requestAnimationFrame(updateDisplay);

    }



    requestAnimationFrame(updateDisplay);



    // ドラッグ機能

    let isDragging = false;

    let offsetX, offsetY;



    counterContainer.addEventListener('mousedown', (e) => {

        isDragging = true;

        counterContainer.style.cursor = 'grabbing';

        offsetX = e.clientX - counterContainer.getBoundingClientRect().left;

        offsetY = e.clientY - counterContainer.getBoundingClientRect().top;

    });



    document.addEventListener('mouseup', () => {

        isDragging = false;

        counterContainer.style.cursor = 'grab';

    });



    document.addEventListener('mousemove', (e) => {

        if (!isDragging) return;



        counterContainer.style.left = e.clientX - offsetX + 'px';

        counterContainer.style.top = e.clientY - offsetY + 'px';

    });



    // 照準の表示/非表示を切り替え

    crosshairToggle.addEventListener('change', function() {

        crosshairElement.style.display = this.checked ? 'block' : 'none';

    });



})();