Greasy Fork is available in English.

Antimisclic

Avoid the unintentional misclics and mouse slips on your chess.com chess games.

// ==UserScript==
// @name         Antimisclic
// @namespace    YGL
// @version      1.0
// @description  Avoid the unintentional misclics and mouse slips on your chess.com chess games.
// @license      Gnu GPL-3.0
// @author       Benjamin Moine
// @match        https://www.chess.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var detectionDelay = 1000; // Définir le délai de détection par défaut (en millisecondes)
    var audioSrc = ''; // Chemin du fichier audio
    var antiMisclicActivated = false; // Variable pour suivre l'état du script
    var configDelayButton = null; // Bouton pour configurer le délai de détection
    var configSoundButton = null; // Bouton pour configurer le son de refus de clic

    // Fonction pour détecter les glissements de doigts tactiles
    function handleTouchMove(event) {
        if (!antiMisclicActivated) return; // Sortir de la fonction si le script n'est pas activé

        var lastTouch = handleTouchMove.lastTouch || {};
        var now = Date.now();
        var timeDiff = now - (lastTouch.time || 0);
        var touch = event.touches[0]; // Prendre la première touche pour simplifier

        // Calculer la distance parcourue depuis le dernier mouvement
        var deltaX = touch.clientX - (lastTouch.x || 0);
        var deltaY = touch.clientY - (lastTouch.y || 0);
        var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

        // Calculer la vélocité
        var velocity = distance / timeDiff;

        // Vérifier si la distance parcourue est anormalement grande en un court laps de temps
        // et si la vélocité est également significative
        if (timeDiff > detectionDelay && distance > 50 && velocity > 1.5) {
            // Vérifier si le mouvement est principalement horizontal ou vertical
            var angle = Math.abs(Math.atan2(deltaY, deltaX));

            if (angle < Math.PI / 4 || angle > 3 * Math.PI / 4) {
                // Mouvement principalement horizontal
                console.log("Détection d'un glissement de doigt horizontal !");
                event.preventDefault(); // Empêcher le comportement par défaut (clic)
                // Jouer le son de refus de clic
                if (audioSrc) {
                    playAudio(audioSrc);
                }
            } else {
                // Mouvement principalement vertical
                console.log("Détection d'un glissement de doigt vertical !");
            }
        }

        handleTouchMove.lastTouch = {
            x: touch.clientX,
            y: touch.clientY,
            time: now
        };
    }

    // Fonction pour jouer un fichier audio
    function playAudio(src) {
        var audio = new Audio(src);
        audio.play();
    }

    // Fonction pour activer ou désactiver le script
    function toggleScript() {
        antiMisclicActivated = !antiMisclicActivated;
        var message = antiMisclicActivated ? "Antimisclic activé" : "Activer Antimisclic";
        console.log(message);
        configDelayButton.style.display = antiMisclicActivated ? 'none' : 'block'; // Masquer le bouton de configuration du délai lorsque le script est activé
        configSoundButton.style.display = antiMisclicActivated ? 'none' : 'block'; // Masquer le bouton de configuration du son lorsque le script est activé
        configSoundButton.textContent = antiMisclicActivated ? 'Désactiver Antimisclic' : 'Choix du clic';
        configSoundButton.style.backgroundColor = antiMisclicActivated ? 'green' : 'blue';
        button.textContent = antiMisclicActivated ? 'Antimisclic Activé' : 'Activer Antimisclic';
        button.style.backgroundColor = antiMisclicActivated ? 'green' : 'blue';
    }

    // Fonction pour ouvrir la configuration du délai
    function openDelayConfig() {
        var delay = prompt("Veuillez entrer le délai de détection (en millisecondes) :", detectionDelay);
        detectionDelay = parseInt(delay) || detectionDelay; // Utiliser la valeur par défaut si la saisie n'est pas valide
        configDelayButton.style.display = 'none'; // Cacher le bouton après avoir configuré le délai
    }

    // Fonction pour ouvrir la configuration du son
    function openSoundConfig() {
        var soundUrl = prompt("Veuillez entrer l'URL du fichier audio :", audioSrc);
        audioSrc = soundUrl.trim(); // Utiliser l'URL saisie
        configSoundButton.style.display = 'none'; // Cacher le bouton après avoir configuré le son
    }

    // Ajouter un gestionnaire d'événements pour les mouvements tactiles sur le plateau
    document.addEventListener('touchmove', handleTouchMove);

    // Créer un bouton pour activer/désactiver le script
    var button = document.createElement('button');
    button.textContent = 'Activer Antimisclic';
    button.style.backgroundColor = 'blue';
    button.style.color = 'white';
    button.style.position = 'fixed';
    button.style.top = '10px'; // Aligner en haut
    button.style.left = '50%';
    button.style.transform = 'translateX(-50%)'; // Centrer horizontalement
    button.onclick = toggleScript;
    document.body.appendChild(button);

    // Créer un bouton pour configurer le délai de détection
    configDelayButton = document.createElement('button');
    configDelayButton.textContent = 'Configurer le délai';
    configDelayButton.style.backgroundColor = 'blue';
    configDelayButton.style.color = 'white';
    configDelayButton.style.position = 'fixed';
    configDelayButton.style.top = '10px'; // Aligner en haut
    configDelayButton.style.left = 'calc(50% + 120px)'; // Décaler à droite du bouton "Activer Antimisclic"
    configDelayButton.onclick = openDelayConfig;
    configDelayButton.style.display = 'none'; // Cacher par défaut
    document.body.appendChild(configDelayButton);

    // Créer un bouton pour configurer le son de refus de clic
    configSoundButton = document.createElement('button');
    configSoundButton.textContent = 'Choix du clic';
    configSoundButton.style.backgroundColor = 'blue';
    configSoundButton.style.color = 'white';
    configSoundButton.style.position = 'fixed';
    configSoundButton.style.top = '10px'; // Aligner en haut
    configSoundButton.style.left = 'calc(50% + 240px)'; // Décaler à droite du bouton de configuration du délai
    configSoundButton.onclick = openSoundConfig;
    configSoundButton.style.display = 'none'; // Cacher par défaut
    document.body.appendChild(configSoundButton);

    // Ajouter un gestionnaire d'événements pour les combinaisons de touches de raccourci pour activer/désactiver le script
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.altKey && event.key === 'j') {
            toggleScript();
        }
    });

    // Ajouter un gestionnaire d'événements pour les combinaisons de touches de raccourci pour ouvrir la configuration du délai
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.altKey && event.key === 'o') {
            configDelayButton.style.display = 'block'; // Afficher le bouton de configuration du délai
        }
    });

    // Ajouter un gestionnaire d'événements pour les combinaisons de touches de raccourci pour ouvrir la configuration du son
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.altKey && event.key === 's') {
            configSoundButton.style.display = 'block'; // Afficher le bouton de configuration du son
        }
    });

    // Ajouter un gestionnaire d'événements pour les combinaisons de touches de raccourci pour cacher le bouton de configuration du délai
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.altKey && event.key === 'o') {
            configDelayButton.style.display = 'none'; // Cacher le bouton de configuration du délai
        }
    });

})();