FreeMobile TinyAuth

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

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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);
}

})();