Greasy Fork

Greasy Fork is available in English.

FreeMobile TinyAuth

Retour à l'ancien mode d'identification sur FreeMobile.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name           FreeMobile TinyAuth
// @namespace      freemobile
// @description    Retour à l'ancien mode d'identification sur FreeMobile.
// @include        https://mobile.free.fr/*
// @version        2.7.1
// @grant          all
// @run-at         document-start
// ==/UserScript==
(function () {

var version = "2.7.1";

var debug = false;
var imgs = [];
var isOpera = false;

var options = {
    timer: 1, // utiliser une temporisation avant l'envoi du formulaire (defaut: oui).
    timerSubmit : 2000 // temps de la temporisation.
}
try {
    if (!unsafeWindow) {
        unsafeWindow = window;
    }
} catch (e) {}

if (GM_getValue == undefined && window.localStorage != undefined) {
    var GM_getValue = function (name) {
        if (name in options) {
            var v = window.localStorage.getItem(name);
            if (v != null) {
                return v;
            }
            return options[name];
        }
        return null;
    };
}
if (GM_setValue == undefined && window.localStorage != undefined) {
    var GM_setValue = function (name, value) {
        if (name in options) {
            return window.localStorage.setItem(name, value);
        }
    };
}

var saveOptions = function () {
    for (option in options) {
        GM_setValue(option, options[option]);
    }
};
var loadOptions = function () {
    for (option in options) {
        options[option] = GM_getValue(option);
    }
};
loadOptions();

var convert_color = function (image_data) {
    for (var x = 0; x < image_data.width; x++) {
        for (var y = 0; y < image_data.height; y++) {
            var i = x*4+y*4*image_data.width;
            var luma = Math.floor(image_data.data[i] * 299/1000 +
            image_data.data[i+1] * 587/1000 +
            image_data.data[i+2] * 114/1000);

            image_data.data[i] = luma;
            image_data.data[i+1] = luma;
            image_data.data[i+2] = luma;
            image_data.data[i+3] = 255;
            if (image_data.data[i] > 200 || image_data.data[i+3] == 0) {
                image_data.data[i] = 255;
                image_data.data[i+1] = 255;
                image_data.data[i+2] = 255;
                image_data.data[i+3] = 0;
            }
        }
    }
};

if (debug) {
    var testDecode = function () {
        console.log("Start test ...");
        var canvas, ctx, imageData;
        var debugCanvas, debugCtx;
        var number, numbers = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
        var debugCanvas = document.createElement("canvas");
        debugCanvas.setAttribute("width", 10*10);
        debugCanvas.setAttribute("height", 16);
        form.appendChild(debugCanvas);
        var debugCtx = debugCanvas.getContext('2d');
        canvas = document.createElement("canvas");
        canvas.setAttribute("width", 10);
        canvas.setAttribute("height", 16);
        ctx = canvas.getContext('2d');
        for (var i = 0; i < 10; i++) {
            var img = imgs[i];
            ctx.fillStyle = "rgb(255,255,255)";
            ctx.fillRect(0,0,10,16);
            ctx.drawImage(img, 14, 12, 10, 16, 0, 0, 10, 16);
            imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            number = get_numberV2(imageData);
            console.log(number, imageData);
            ctx.putImageData(imageData, 0, 0);
            debugCtx.drawImage(canvas, 0, 0, 10, 16, 10*i, 0, 10, 16);
        }
        console.log("Done.");
    };
}

var get_numberV1 = function(image_data) {
    convert_color(image_data);
    var idx = 34;
    var test = 0;
    for (var i = 0; i < 10; i++) {
        if (image_data.data[(idx+i*10)*4+3] > 0) {
            break;
        }
    }
    if (i == 10) { // 0
        return 0;
    }
    var idx = 6;
    for (var i = 0; i < 15; i++) {
        if (image_data.data[(idx+i*10)*4+3] == 0) {
            break;
        }
    }
    if (i == 15) { // 1 3 4 8 9
        idx = 103; // 4
        if (image_data.data[idx*4+3] > 0 && image_data.data[(idx+2)*4+3] > 0) {
            return 4;
        }
        idx = 34; // 1
        if (image_data.data[idx*4+3] > 0) {
            return 1;
        }
        idx = 102; // 9
        if (image_data.data[idx*4+3] == 0 && image_data.data[(idx+1)*4+3] == 0) {
            return 9;
        }
        idx = 92; // 3
        if (image_data.data[idx*4+3] == 0) {
            return 3;
        }
        return 8;
    }
    if (image_data.data[72*4+3] > 0 && image_data.data[92*4+3] == 0) { // 5
        return 5;
    }
    if (image_data.data[88*4+3] > 0) { // 6
        return 6;
    }
    if (image_data.data[42*4+3] > 0) {
        return 2;
    }
    return 7;
};

var get_numberV2 = function(image_data) {
    convert_color(image_data);
    var idx = 34;
    var test = 0;
    for (var i = 0; i < 10; i++) {
        if (image_data.data[(idx+i*10)*4+3] > 0) {
            break;
        }
    }
    if (i == 10) { // 0
        return 0;
    }
    var idx = 6;
    for (var i = 0; i < 15; i++) {
        if (image_data.data[(idx+i*10)*4+3] == 0) {
            break;
        }
    }
    if (i == 15) { // 1 3 4
        idx = 103; // 4
        if (image_data.data[idx*4+3] > 0 && image_data.data[(idx+2)*4+3] > 0) {
            return 4;
        }
        idx = 34; // 1
        if (image_data.data[idx*4+3] > 0) {
            return 1;
        }
        idx = 92; // 3
        if (image_data.data[idx*4+3] == 0) {
            return 3;
        }
    }
    if (image_data.data[72*4+3] > 0 && image_data.data[92*4+3] == 0) { // 5
        return 5;
    }
    if (image_data.data[88*4+3] > 0) { // 6 8 9
        if (image_data.data[61*4+3] == 0) {
            return 8;
        }
        if (image_data.data[101*4+3] == 0) {
            return 9;
        }
        return 6;
    }
    if (image_data.data[42*4+3] > 0) {
        return 2;
    }
    return 7;
};

var decodeV1 = function () {
    if (debug) {
        console.log("Decodeur V1");
    }
    var canvas, ctx, imageData;
    var debugCanvas, debugCtx;
    var number, numbers = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
    // start debug
    if (debug) {
        var debugCanvas = document.createElement("canvas");
        debugCanvas.setAttribute("width", 10*10);
        debugCanvas.setAttribute("height", 16);
        form.appendChild(debugCanvas);
        var debugCtx = debugCanvas.getContext('2d');
    }
    // end debug
    canvas = document.createElement("canvas");
    canvas.setAttribute("width", 10);
    canvas.setAttribute("height", 16);
    ctx = canvas.getContext('2d');
    for (var i = 0; i < 10; i++) {
        var img = imgs[i];
        ctx.fillStyle = "rgb(255,255,255)";
        ctx.fillRect(0,0,10,16);
        ctx.drawImage(img, 14, 12, 10, 16, 0, 0, 10, 16);
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        number = get_numberV1(imageData);
        // start debug
        if (debug) {
            console.log(number);
            ctx.putImageData(imageData, 0, 0);
            debugCtx.drawImage(canvas, 0, 0, 10, 16, 10*i, 0, 10, 16);
        }
        // end debug
        if (number < 0 || number > 9 || numbers[number] != -1) {
            throw new Error("Décodage échoué.");
        }
        if (number != undefined) {
            numbers[number] = i;
        }
    }
    return numbers;
};

var decodeV2 = function () {
    if (debug) {
        console.log("Decodeur V2");
    }
    var canvas, ctx, imageData;
    var debugCanvas, debugCtx;
    var number, numbers = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
    // start debug
    if (debug) {
        var debugCanvas = document.createElement("canvas");
        debugCanvas.setAttribute("width", 10*10);
        debugCanvas.setAttribute("height", 16);
        form.appendChild(debugCanvas);
        var debugCtx = debugCanvas.getContext('2d');
    }
    // end debug
    canvas = document.createElement("canvas");
    canvas.setAttribute("width", 10);
    canvas.setAttribute("height", 16);
    ctx = canvas.getContext('2d');
    for (var i = 0; i < 10; i++) {
        var img = imgs[i];
        ctx.fillStyle = "rgb(255,255,255)";
        ctx.fillRect(0,0,10,16);
        ctx.drawImage(img, 14, 12, 10, 16, 0, 0, 10, 16);
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        number = get_numberV2(imageData);
        // start debug
        if (debug) {
            console.log(number);
            ctx.putImageData(imageData, 0, 0);
            debugCtx.drawImage(canvas, 0, 0, 10, 16, 10*i, 0, 10, 16);
        }
        // end debug
        else if (number < 0 || number > 9 || numbers[number] != -1) {
            throw new Error("Décodage échoué.");
        }
        if (number != undefined) {
            numbers[number] = i;
        }
    }
    return numbers;
};

var decodeSND = function () {
    if (debug) {
        console.log("Decodeur via le son");
    }
    var number, numbers = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];
    var map = {
        "17135": 0,
        "9825":  1,
        "15045": 2,
        "16299_3": 3,
        "16299_4": 4,
        "18807": 5,
        "18389": 6,
        "17971": 7,
        "16717": 8,
        "17553": 9
    };
    var soundManager = unsafeWindow.soundManager;
    if (undefined == soundManager) {
        throw new Error("Décodage échoué.");
    }
    for (var i = 0; i < 10; i++) {
        if (!soundManager.getSoundById("sound"+i)) {
            throw new Error("Décodage échoué.");
        }
        var bytes = soundManager.getSoundById("sound"+i).bytesTotal;
        if (bytes == 16299) {
            if (numbers[3] > -1) {
                number = 4;
            } else if (numbers[4] > -1) {
                number = 3;
            } else {
                canvas = document.createElement("canvas");
                canvas.setAttribute("width", 10);
                canvas.setAttribute("height", 16);
                ctx = canvas.getContext('2d');
                var img = imgs[i];
                ctx.fillStyle = "rgb(255,255,255)";
                ctx.fillRect(0,0,10,16);
                ctx.drawImage(img, 14, 12, 10, 16, 0, 0, 10, 16);
                imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                number = get_numberV2(imageData);
            }
        } else {
            number = map[bytes];
        }
        if (number < 0 || number > 9 || numbers[number] != -1) {
            throw new Error("Décodage échoué.");
        }
        if (debug) {
            console.log("Sound "+i+" => "+number);
        }
        numbers[number] = i;
    }
    return numbers;
};

var decode = function () {
    var numbers;
    var ok = false;
    try {
        numbers = decodeV2();
        ok = true;
    } catch (e) {}
    if (!ok) {
        try {
            numbers = decodeV1();
            ok = true;
        } catch (e) {}
    }
    if (!ok) {
        try {
            numbers = decodeSND();
            ok = true;
        } catch (e) {}
    }
    if (!ok) {
        throw new Error("Décodage échoué.");
    }
    return numbers;
};

var form;
var hiddePanel = function () {
    form.addEventListener("submit", sendForm, true);
    var els = form.querySelectorAll("*");
    for (var j = 1; j < els.length; j++) {
        if (els[j].tagName != "TABLE" && (form == els[j].parentNode || els[j].tagName == "SPAN")) {
            els[j].oldDisplay = els[j].style.display;
            els[j].style.display = "none";
        }
    }
    var label = document.querySelector("#content>span");
    if (label) {
        label.style.display = "none";
    }
    var buttonsContainer = document.querySelector(".ident_chiffre2");
    if (buttonsContainer) {
        buttonsContainer.style.display = "none";
    }
    var submit = document.querySelectorAll("form button[type=submit]")[0];
    if (submit) {
        submit.parentNode.style.display = "block";
    }
};

var displayPanel = function () {
    form.removeEventListener("submit", sendForm, true);
    var els = form.querySelectorAll("*");
    for (var j = 1; j < els.length; j++) {
        if (els[j].tagName != "TABLE" && (form == els[j].parentNode || els[j].tagName == "SPAN")) {
            els[j].style.display = "block";
        }
    }
    var label = document.querySelector("#content>span");
    if (label) {
        label.style.display = "block";
    }
    var buttonsContainer = document.querySelector(".ident_chiffre2");
    if (buttonsContainer) {
        buttonsContainer.style.display = "block";
    }
};

var count = 0;
var timerSubmit = function () {
    var realTimer = parseInt(options.timerSubmit) + 500;
    if (options.timer == 0) {
        document.getElementById("msgSubmit").innerHTML = "Connexion en cours (normalement) ...";
        return;
    }
    if (count >= realTimer) {
        count = 0;
        document.getElementById("msgSubmit").innerHTML = "Connexion en cours (normalement) ...";
        return;
    }
    count += 1000;
    if (count > realTimer) {
        count = realTimer;
    }
    document.getElementById("msgSubmit").innerHTML = "Connexion dans "+parseInt((realTimer - count) / 1000)+" secondes ...";
    setTimeout(timerSubmit, 1000);
};

var ready = 0;
var timerImagesSmall = function (numbers) {
    ready = 0;
    var id = document.getElementById("ident_login").value.split("");
    document.getElementById("msgSubmit").style.display = "block";
    timerSubmit();
    var fnReady = function () {
        ready += 1;
        if (ready == 9) {
            document.getElementById("msgSubmit").style.display = "block";
            form.submit();
        } else if (ready < 9) {
            if (options.timer == 1) {
                setTimeout(loadNext, 500);
            }
        }
    };
    var cursor = 0;
    var loadNext = function () {
        var img = document.createElement("img");
        img.onload = fnReady;
        img.src = "chiffre.php?pos="+numbers[id[cursor]]+"&small=1";
        img.style.visibility = "hidden";
        document.body.appendChild(img, document.getElementById("ident_login"));
        cursor++;
    };
    if (options.timer == 0) {
        for (var j = 0; j < 10; j++) {
            loadNext();
        }
    } else {
        loadNext();
    }
};

var sendForm = function (e) {
    if (debug || ready < 8) {
        e.preventDefault();
    }
    if (ready == 8) {
        return;
    }
    var newInput = document.getElementById("ident_login");
    var numbers;
    try {
        numbers = decode();
    } catch(e) {
        displayPanel();
        var span = document.createElement("span");
        span.innerHTML = 'Détection automatique impossible : <a href="https://github.com/Blount/FreeMobile_TinyAuth">surveillez les mises à jour</a>.';
        span.style.fontWeight = "bold";
        document.getElementById("ident_blocd").insertBefore(span,
            document.getElementById("ident_div_ident"));
        newInput.parentNode.removeChild(newInput);
        return;
    }
    var ident = "";
    var n, id = newInput.value.split("");

    for (var j = 0; j < id.length; j++) {
        n = parseInt(id[j]);
        if (n >= 0 && n <= 9) {
            ident += numbers[n];
        }
    }
    timerImagesSmall(numbers);
    newInput.setAttribute("name", "");
    document.getElementById("ident_pos").value = ident;
};

var drawScriptPanel = function () {
    isOpera = window.navigator.appName.match("Opera");
    // custom CSS
    var style = document.createElement("style");
    style.setAttribute("type", "text/css");
    style.innerHTML  = "<!-- ";
    style.innerHTML += " .tinyAuthContainer {position: absolute; top: 0; right: 20px; text-align: center; ";
    style.innerHTML += " padding: 5px 20px; background: #F5F5F5; border: 2px solid #DDDDDD; box-shadow: 0 0 5px #CCC; }";
    style.innerHTML += " .tinyAuthContainer a:link, .tinyAuthContainer a:hover, .tinyAuthContainer a:active, .tinyAuthContainer a:visited {";
    style.innerHTML += " color: #333333; font-weight: bold;}";
    style.innerHTML += " .tinyAuthContainer span.title { font-weight: bold; color: #EF0000; }";
    style.innerHTML += " .tinyAuthContainer div.infos input { background: #F0F0F0; border: 1px solid #E5E5E5; color: #333333; border-radius: 4px; font-size: 9px; cursor: pointer; }";
    style.innerHTML += " .tinyAuthContainer .options {text-align: left; ";
    style.innerHTML += " padding: 5px 20px; background: #FFFFFF; border: 2px solid #DDDDDD; display: none; }";
    style.innerHTML += " -->";
    document.head.appendChild(style);

    var url = isOpera?"http://ilatumi.org/FreeMobile_TinyAuth.oex":"https://github.com/Blount/FreeMobile_TinyAuth/raw/master/freemobile_tinyauth.user.js";
    var container = document.createElement("div");
    container.setAttribute("class", "tinyAuthContainer");
    var contentHTML = "";
    contentHTML += '<span class="title">TinyAuth '+version+'</span> : <a href="https://github.com/Blount/FreeMobile_TinyAuth">Home</a> | ';
    contentHTML += '<a href="'+url+'">';
    contentHTML += '<img src="http://ilatumi.org/tinyauth-freemobile/version.php?v='+version+'" alt="Test de version en cours …" style="vertical-align: middle;" /></a>';
    contentHTML += '<div class="infos">';
    contentHTML += '    <input type="button" value="Afficher le pavé numérique" id="togglePanel" />';
    contentHTML += '    <input type="button" value="+ options" id="tinyAuthtoggleOptions" />';
    contentHTML += '</div>';
    contentHTML += '<div class="options" id="tinyAuthOptionsContainer">';
    contentHTML += '<label><input type="checkbox" name="timer" id="tinyAuth-active-timer" value="1" class="clickclick" /> activer le temps d\'attente avant connexion</label>';
    contentHTML += '<p style="text-align: center; margin:0;"><input type="button" id="tinyAuth-closeoptions" value="OK" />';
    contentHTML += '</div>';
    container.innerHTML = contentHTML;
    var header = document.getElementById("header");
    if (!header) {
        header = document.head;
    } else {
        header.style.position = "relative";
    }
    document.getElementById("header").appendChild(container);
    document.getElementById("togglePanel").addEventListener("click", function () {
        if (form.querySelectorAll("span.red")[0].style.display == "none") {
            this.value = "Masquer le pavé numérique";
            displayPanel();
        } else {
            this.value = "Afficher le pavé numérique";
            hiddePanel();
        }
    }, false);
    var toggleOptions = function () {
        if (document.getElementById("tinyAuthOptionsContainer").style.display != "block") {
            document.getElementById("tinyAuthOptionsContainer").style.display = "block";
        } else {
            document.getElementById("tinyAuthOptionsContainer").style.display = "none";
        }
    };
    document.getElementById("tinyAuthtoggleOptions").addEventListener("click", toggleOptions, false);
    document.getElementById("tinyAuth-closeoptions").addEventListener("click", toggleOptions, false);
    var els = container.querySelectorAll(".clickclick");
    for (var i = 0; i < els.length; i++) {
        els[i].addEventListener("click", function (e) {
            var type = this.getAttribute("type");
            if (type == "checkbox") {
                options[this.getAttribute("name")] = this.checked?1:0;
            }
            saveOptions();
        }, false);
    }
    for (option in options) {
        var el = container.querySelectorAll("*[name="+option+"]");
        if (el.length) {
            var type = el[0].getAttribute("type");
            if (type == "checkbox") {
                el[0].checked = options[option] != 0?"checked":"";
            }
        }
    }
};
var start = function () {
    if (!document.getElementById("ident_pos")) {
        return;
    }
    //~ document.body.appendChild(customForm);
    drawScriptPanel();
    var forms = document.getElementsByTagName("form");
    if (forms.length > 0) {
        for (var k = 0; k < forms.length; k++) {
            var submit = forms[k].querySelectorAll("form button[type=submit]")[0];
            if (forms[k].style.display != "none" && submit && submit.style.display != "none") {
                form = forms[k];
            }
        }
    }
    var imgsEl = document.querySelectorAll(".ident_chiffre2 li img");
    for (var i = 0; i < imgsEl.length; i++) {
        var attr = imgsEl[i].getAttribute("onmouseover");
        if (attr && false != attr.indexOf("getVoiceStatus")) {
            imgs.push(imgsEl[i]);
        }
    }
    var identPos = document.getElementById("ident_pos");
    var newInput = document.createElement("input");
    newInput.setAttribute("type", "text");
    newInput.setAttribute("id", "ident_login");
    newInput.setAttribute("autocomplete", "On");
    newInput.setAttribute("name", "ident_login");
    identPos.parentNode.appendChild(newInput);
    var msgSubmit = document.createElement("p");
    msgSubmit.setAttribute("id", "msgSubmit");
    msgSubmit.style.display = "none";
    msgSubmit.style.fontWeight = "bold";
    msgSubmit.style.textAlign = "right";
    msgSubmit.style.clear = "both";
    form.appendChild(msgSubmit);
    hiddePanel();
};

if (typeof unsafeWindow != "undefined") {
    document.addEventListener ("readystatechange", function () {
        if (document.readyState == "interactive") {
            start();
        }
    }, true);
} else {
    document.addEventListener("DOMContentLoaded", start, false);
}

})();