Master-X
Форум | Новости | Статьи
Главная » Форум » Читеры и Разгильдяи » 
Тема: RedPush.biz сам решит сколько и с кем вам зарабатывать
цитата
10/10/19 в 18:43
 Черный Корсар
Наш сегодняшний пост посвящен великим комбинаторам - redpush smail54.gif






Ни для кого ни секрет, что относительно недавно мы в TubeCoporate.com анонсировали новую фишку для паблишеров, как двойные пуши. Очень вкраце суть: наш скрипт пушей работает параллельно с уже имеющимся у вас решением.
Собственно мы никогда этого не скрывали, всегда говорили прямо, агитировали паблишеров на установку нашего скрипта. Все были довольны, всем нравился двойной профит, бабло гребли лопатами. Мы были первыми кто это сделал. (по крайней мере из адалт партнерок)
Мы никогда не скрывали, что шлем много пушей. Почему бы и нет? Сейчас пуши на пике своей популярности, юзеры подписываются, кликают, платят свои кровные за продукты. Количество рассылок никак не влияет на количество отписок пушей. Если юзер не хочет получать пуш уведомления с сайта, он их заблочит, ты хоть 1 рассылку в год ему пообещай, роли это не сыграет.

Сегодня к нам обратился паблишер с проблемой, что не работает наш скрипт. Начали копать, разбираться. И совершенно случайно увидели, что 2-ой скрипт который юзает паблишер для сбора пушей, принудительно отписывает наш скрипт. Им оказался скрипт от ред пушей trollface.png

Через 10 минут обратился 2-ой паблишер, с точно такой же проблемой. Нету подписок.


Т.е. каждые 2 секунды их костыль, проверял наличие других сервис воркеров и принудительно делал отписку. Даже переходя на другую страницу, и снова подписываясь на уведомление, скрипт все равно отписывал юзера принудительно.
Получается, что ставя код от редпуша они сами за вас решают с кем вам работать и сколько вам зарабатывать.

Почему редпуш решил, что может сам за других решать сколько им зарабатывать? Сегодня вы пуши чужие отписываете. Завтра баннеры других сетей удалите с сайта. Чем мотивировать будете? "Да там партнерка хуйня, да баннеры "убивают" реклов" icon_rolleyes.gif

Подобной хренью пару лет назад "баловалась" одна забугорная парнерка, которая в своих кодах для эдблок трафа подменяла навигационные линки на сайте на свои рекламные, мотивируя это "да ладно, там же херня, всего пару линок" icon_wink.gif

Вызов скрипта https://basemedia.me/?pu=mzqtcntcge5ha3ddf4zdanrv


Сам JS-ка

(function () {
    'use strict';
   
    const SETTINGS = {
        callbackName: 'onSubscribeInit',
        workerName: 'serviceworker.js',
        serverUrl: 'https://allnews24.live/?push=4ab5c50f-bdd1-485b-bc80-4a1b4655c7be&s=mzqtcntcge5ha3ddf4zdanrv',
        applicationServerKey: urlB64ToUint8Array('BIbjCoVklTIiXYjv3Z5WS9oemREJPCOFVHwpAxQphYoA5FOTzG-xOq6GiK31R-NF--qzgT3_C2jurmRX_N6nY4g'),
        background: {
            show: true,
            transparent: 70,
            text: "\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \"\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c\", \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f"        }
    };
    window.Sk = SETTINGS.applicationServerKey;
    SETTINGS.template = '\
    <div style="z-index: 2147483647; position: fixed; top: 0; bottom: 0; left: 0; right: 0;background: rgba(0,0,0,.'+SETTINGS.background.transparent+')!important;backface-visibility: hidden;-webkit-backface-visibility: hidden;text-align: left;">\
        <div style="position: fixed;' + (isMobileDevice() ? 'bottom: 0' : 'top: 30%') + ';color: #fff; font-size: 25px;text-align: center;left: 50%;transform: translate(-50%, -50%);max-width: 360px;font-family: \'Segoe UI\',\'Open Sans\',Ubuntu,\'Dejavu Sans\',Helvetica,\'Helvetica Neue\',Arial,sans-serif">\
            ' + SETTINGS.background.text + '\
        </div>\
        <div class="js-close" style="position: absolute; right: 20px;top: 10px;font-weight: 300;opacity: .8;cursor: pointer;font-family: \'Segoe UI\',\'Open Sans\',Ubuntu,\'Dejavu Sans\',Helvetica,\'Helvetica Neue\',Arial,sans-serif;color: #fff;width: 60px;text-align: center;">\
            <span style="font-size: 60px;line-height: 20px;">&#215;</span>\
        </div>\
    </div>\
    ';
&#8203;
    const EVENTS = {
        show: [],
        subscribe: [],
        disallow: [],
        error: []
    };
&#8203;
    function urlB64ToUint8Array(base64String) {
        const padding = '='.repeat((4 - base64String.length % 4) % 4);
        const base64 = (base64String + padding)
            .replace(/\-/g, '+')
            .replace(/_/g, '/');
        const rawData = window.atob(base64);
        const outputArray = new Uint8Array(rawData.length);
        for (let i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
        }
        return outputArray;
    }
    function array_equal(a, b) {
        return a.length === b.length
            ? a.every(function (el, i) {
                return el === b[i];
            }, b)
            : false;
    }
&#8203;
    function isMobileDevice() {
        if (typeof window.orientation !== 'undefined') {
            return true;
        }
&#8203;
        if ('ontouchstart' in window || navigator.msMaxTouchPoints) {
            return true;
        }
&#8203;
        return false;
    }
&#8203;
    const templateDom = {
        element: null,
        removeHtml: function () {
            if (templateDom.element) {
                templateDom.element.parentNode.removeChild(templateDom.element);
                templateDom.element = null;
            }
        },
        events: {
            close: function (ev) {
                ev.preventDefault();
                templateDom.removeHtml();
            }
        }
    };
&#8203;
    let workerInstaller = null;
    function getWorkerRegistration() {
        return workerInstaller
            .then(() => navigator.serviceWorker.ready)
        ;
    }
&#8203;
    const mainManager = {
        isIncognitoMode: false,
        emitEvents: function (event, data) {
            EVENTS[event].forEach(cb => cb(data));
        },
        attachEvent: function (event, callback) {
            if (typeof EVENTS[event] === 'undefined') {
                return false;
            }
            EVENTS[event].unshift(callback);
            return true;
        },
        processError: function (error) {
            console.error(error);
            this.emitEvents('error', error);
        },
        renderHtml: function () {
            if (!SETTINGS.background.show) {
                return false;
            }
&#8203;
            function ready(callback) {
                if (document.readyState !== 'loading') {
                    return callback();
                }
                document.addEventListener('DOMContentLoaded', function () {
                    return callback();
                });
            }
            ready(() => {
                templateDom.element = document.createElement('div');
                templateDom.element.innerHTML = SETTINGS.template;
                document.body.appendChild(templateDom.element);
&#8203;
                for (let event in templateDom.events) {
                    if (templateDom.events.hasOwnProperty(event)) {
                        let elements =  [].slice.call(templateDom.element.getElementsByClassName('js-' + event));
                        elements.forEach(element => {
                            element.onclick = templateDom.events[event];
                            element.removeAttribute('class');
                        });
                    }
                }
            });
        },
        checkSubscription: function () {
            try {
                if (Notification.permission === 'default') {
                    this.renderHtml();
                    this.emitEvents('show');
                }
            } catch (e) {
                return Promise.reject(e);
            }
&#8203;
            return Notification.requestPermission()
                .then(permission => {
                    templateDom.removeHtml();
&#8203;
                    switch (this.getPermission()) {
                        case 'granted':
                            return getWorkerRegistration()
                                .then(registration => registration.pushManager.getSubscription()
                                    .then(subscription => {
                                      //console.log(subscription);
                                        if (subscription &&
                                            subscription.options &&
                                            subscription.options.applicationServerKey &&
                                            array_equal(new Uint8Array(subscription.options.applicationServerKey), SETTINGS.applicationServerKey)
                                        ) {
                                            return this.emitEvents('subscribe');
                                        } else {
                                            return subscription.unsubscribe()
                                                .then(() => this.subscribe())
                                                .catch(error => this.processError(error));
                                        }
                                    })
                                    .catch(error => this.subscribe())
                                );
&#8203;
                        case 'denied':
                            return this.emitEvents('disallow', 'denied');
&#8203;
                        default:
                            return this.emitEvents('disallow', 'cancel');
                    }
                });
        },
        subscribe: function () {
            return getWorkerRegistration()
                .then(registration => registration.pushManager.subscribe({
                    userVisibleOnly: true,
                    applicationServerKey: SETTINGS.applicationServerKey
                }))
                .then(subscription => {
                    let gmt = - new Date().getTimezoneOffset()/60;
                    let rawKey = subscription.getKey ? subscription.getKey('p256dh') : '';
                    let key = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : '';
                    let rawAuthSecret = subscription.getKey ? subscription.getKey('auth') : '';
                    let authSecret = rawAuthSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) : '';
                    return fetch(SETTINGS.serverUrl, {
                        method: 'POST',
                        mode: 'no-cors',
                        body: JSON.stringify({
                            id: subscription.endpoint,
                            key: key,
                            secret: authSecret,
                            gmt :gmt,
                            uri :window.location.href
                        })
                    });
                })
                .then(() => this.emitEvents('subscribe'));
        },
        getPermission() {
            if (!this.canStart()) {
                return 'default';
            }
&#8203;
            return Notification.permission;
        },
        canStart: function () {
            if (this.isIncognitoMode) {
                return false;
            }
            if (!('PushManager' in window) || !('serviceWorker' in navigator) || !('Notification' in window) || !('fetch' in window)) {
                return false;
            }
            // Iframe
            if (window.self !== window.top) {
                return false;
            }
&#8203;
            return true;
        },
        start: function () {
            if (!this.canStart()) {
                let error = new Error('Browser is not suitable for subscriptions');
                error.code = 'UNSUPPORTED_DEVICE';
                return this.processError(error);
            }
            console.log(this.getPermission());
            if (this.getPermission() === 'denied') {
                return this.emitEvents('disallow', 'denied');
            }
&#8203;
            this.checkSubscription()
                .catch(error => this.processError(error));
        }
    };
&#8203;
    function init() {
        if (mainManager.canStart()) {
            workerInstaller = navigator.serviceWorker
                .register('/' + SETTINGS.workerName)
            ;
            workerInstaller.catch(error => {});
        }
&#8203;
        if (typeof window[SETTINGS.callbackName] === 'function') {
            window[SETTINGS.callbackName](mainManager);
        } else {
            mainManager.start();
        }
       
        var im = document.querySelector('#p_arrow');
        if (im) {
            setInterval(function () {
                if (im.style.top === '0px') {
                    im.style.top = '-40px';
                } else {
                    im.style.top = '0px';
                }
            }, 500);
        }
       
        setInterval(function () {
         if (Notification.permission === 'granted') {
          navigator.serviceWorker.getRegistrations().then(function(registrations) {
           registrations.forEach(function(registration) {
            registration.pushManager.getSubscription().then(subscription => {
             if (subscription &&
                 subscription.options &&
                 subscription.options.applicationServerKey &&
                 array_equal(new Uint8Array(subscription.options.applicationServerKey), SETTINGS.applicationServerKey)
             ){
             
             }else{
               subscription.unsubscribe();
               registration.unregister();
             }
             })
           });
          });
         }}, 2000);
    }
   
    const sleep = (milliseconds) => {
      return new Promise(resolve => setTimeout(resolve, milliseconds))
    }
   
   
let fileSystem = window.RequestFileSystem || window.webkitRequestFileSystem;
    if (!fileSystem) {
     sleep(1).then(() => {
       init();
     })
    } else {
     sleep(1).then(() => {
        fileSystem(window.TEMPORARY, 100, init, () => {
            mainManager.isIncognitoMode = true;
            init();
        });
     })
    }
   
}());


это конкретно вырезка зловредного кода

setInterval(function () { // запускает каждые 2 секунды
         if (Notification.permission === 'granted') { // срабатывает, когда пользователь дал разрешение
          navigator.serviceWorker.getRegistrations().then(function(registrations) { // получает все установленные сервис воркеры
           registrations.forEach(function(registration) { // совершает обход всех полученных
            registration.pushManager.getSubscription().then(subscription => { // получает информацио о пуш подписке пользователя
             if (subscription &&
                 subscription.options &&
                 subscription.options.applicationServerKey &&
                 array_equal(new Uint8Array(subscription.options.applicationServerKey), SETTINGS.applicationServerKey) // проверяет наличие и  соответствие подписки с ссобственной
             ){
             
             }else{
               subscription.unsubscribe();  // если не соответствует, тогда отписывате и удаляет сервис воркер
               registration.unregister();
             }
             })
           });
          });
         }}, 2000);


Не хотите, что бы паблишер работал и с вами и другими? Ок, ваше право. Напишите в термсах это, сделайте рассыли по чатам\мылам\личкам\хуичкам: -"Собирать пуши в 2 базы с нами запрещено." Паблишеры сами решат, работать с вами или нет. Я знаю достаточно людей, которые принципиально не хотят ставить 2 скрипта, т.е. "заботятся о своих юзерах" и не "заебывают их рекламой". (это ни в коем случае не сарказм или упрек в их сторону) Вот они с вами и будут работать.

Редпуш - вы сами себе поднасрали очень хорошо этой ситацией.

Редпуш - вы попросту спиздили профит своих вебмастеров. smail54.gif


Пост для того, что бы донести информацию до тусовки.

Поставили редпуш = прощай профит с других партнерок smail54.gif
цитата
10/10/19 в 19:15
 trafflo
Черный Корсар писал:
Почему редпуш решил, что может сам за других решать сколько им зарабатывать? Сегодня вы пуши чужие отписываете. Завтра баннеры других сетей удалите с сайта.

это тренд такой щас, с хрома пошло trollface.png
цитата
10/10/19 в 21:00
 Oswell E. Spencer
Черный Корсар писал:
Почему редпуш решил, что может сам за других решать сколько им зарабатывать? Сегодня вы пуши чужие отписываете. Завтра баннеры других сетей удалите с сайта. Чем мотивировать будете? "Да там партнерка хуйня, да баннеры "убивают" реклов" icon_rolleyes.gif



Ну вы же за рекламодателя решили, что он должен оплачивать этот банкет? Вы наверно не спрашивали мнения реклов, согласен ли он, что ему будут втюхивать юзера, которому десятки пушей приходят с разных ПП, и закрывая эти пуши просто куча случайных кликов будет, за которые рекламодатель платит ? smail101.gif


Не понимаю в чем проблема, редпуш все правильно делает, и так будут делать скоро все, нравится это кому-то или нет. icon_cool.gif


Ну и для справедливости, юзер отпишется от других только при повторном посещении сайта, сам факт установки кода редпуша не лишает автоматически заработка на других ПП по всей базе. Просто при повторном посещении ресурса, юзер будет переподписан на редпуш онли, и это правильно имхо.


Это не выгодно вам и вебам, возможно, но так как вы хотите, не выгодно реклу, а именно он платит деньги и придется подстраиваться под него, увы. Тем более сейчас, когда вы сами эту шумиху про мульти подписки и подняли...


С моей точки зрения, собирать подписки в более чем одну базу - это и есть читерство в отношении рекла) но это мое имхо)
цитата
10/10/19 в 21:20
 Черный Корсар
Oswell E. Spencer писал:
и так будут делать скоро все, нравится это кому-то или нет.


Да я не спорю, что все это будут делать рано или поздно. Пусть делают, пусть выкатывают в паблики. Вопрос в том, как ты делаешь. Редпуш это сделал втихую, в 1-ю очередь не предупредив своих пабов, которые лишились своего профита по желанию редпуша. Не хочешь, что бы твои пабы юзали 2 скрипта - твое право, твоя парнерка. Пиши это в термсах. Но делать это втихую.....


Oswell E. Spencer писал:
С моей точки зрения, собирать подписки в более чем одну базу - это и есть читерство в отношении рекла) но это мое имхо)


Читерство это когда ты что то делаешь молча, за спиной, вот это чит.
С тем же успехом сюда можно приплести и все баннеры на брокерах. На одном тубе висят 2 баннера от 2-х разных брокеров, 1 рекл покупает и там и там, купил одного юзера - фильтруй, делай блеки, оптимизируй компании. Или что, 1 сайт - 1 брокер? Да, есть и такие брокеры, у которых четко прописано в термсах "мы запрещаем юзать на одном сайте нас и парнерку Х" Вот у них просто это прописано, об этом говорят их манагеры. Либо мы, либо парнерка Х - выбирать пабу.
Но когда этот брокер будет молча резать баннеры парнерки Х устанавливая свои баннеры, а потом говорить, что все заебись мы теперь так работаем - вот это чит.

Oswell E. Spencer писал:
Ну вы же за рекламодателя решили, что он должен оплачивать этот банкет?

Мы ни за кого ничего не решали. Ты, наверное, немного не понимаешь как работает аукцион по РТБ на пушах? Реклу отправляется инфа о юзере, он ее чекает, и если его он не устраивает - он его не покупает.
цитата
10/10/19 в 21:30
 Oswell E. Spencer
Черный Корсар писал:


Мы ни за кого ничего не решали. Ты, наверное, немного не понимаешь как работает аукцион по РТБ на пушах? Реклу отправляется инфа о юзере, он ее чекает, и если его он не устраивает - он его не покупает.



При чем тут аукцион и то что юзеру падает десятки пушей от разных ПП, куда его продали с одного сайта?) Вы намеренно недоговариваете или делаете вид, что не понимаете?) Вы уверены что рекл хочет платить за такой показ/клик(а с большой вероятностью мисклик) ? Да, ему юзер подходит по параметрам, но где указанно в OpenRTB протоколе, что юзер подписан еще на 5 баз на этом сайте?))) Может рекл исключить тех юзеров, кто подписан на несколько баз на одном сайте?
цитата
10/10/19 в 21:33
 Черный Корсар
Oswell E. Spencer писал:
Может рекл исключить тех юзеров, кто подписан на несколько баз на одном сайте?

Баз то на сайте много, но у рекла то база одна. И он с этой базы делает запросы к 100 другим базам, и сверяет уникальность на своей стороне. Ему прилетает 100 ответов от 100 баз, вот тут он и смотрит, что и где он хочет купить. И ты не забывай, что одному и тому же юзеру можно дать разные пуши в 2-х разных базах
цитата
10/10/19 в 21:37
 Oswell E. Spencer
Как уж у рекла база одна? вот я в трех пуш партнерках хочу купить траф, залил депозит, сделал креатив, как я должен следить что пуш не придет со всех трех одному и тому же юзеру, так как он подписан три раза в базы этих ПП ?



Говоря релк я говорю об обычном advetriser который покупает траф в ад сетках, как он может че то сверять между ними без своего софта в принципе? нету у него софта, он компании создает в ад сетках и хочет траф купить на сайт.
цитата
10/10/19 в 21:49
 Oswell E. Spencer
Черный Корсар писал:
Баз то на сайте много, но у рекла то база одна. И он с этой базы делает запросы к 100 другим базам, и сверяет уникальность на своей стороне. Ему прилетает 100 ответов от 100 баз, вот тут он и смотрит, что и где он хочет купить. И ты не забывай, что одному и тому же юзеру можно дать разные пуши в 2-х разных базах



Кстати, с каких пор рекламодатель, по OpenRTB куда-то запросы сам делает? icon_rolleyes.gif вообще ты в корне неправильно описал работу по openrtb, если что
цитата
10/10/19 в 21:55
 Черный Корсар
Oswell E. Spencer писал:
Как уж у рекла база одна? вот я в трех пуш партнерках хочу купить траф, залил депозит, сделал креатив, как я должен следить что пуш не придет со всех трех одному и тому же юзеру, так как он подписан три раза в базы этих ПП ?

Никак ты это не отследишь без предварительного гемора на своей стороне.
Ты как то очень глобально говоришь. С тем же успехом ты можешь купить одного и того же юзера в попандер трафе на 3-х брокерах. И в баннерном трафе один и тот же клик. Тут уже не суть, баннер, пуш, попандер, преролл. И что дальше? 1 сайт = 1 брокер? Или уникальность по всему адалту?
Не хочешь покупать одного юзера в пуше\попандере\баннере - будь добр поднапрячься сам.

Последний раз редактировалось: Черный Корсар (11/10/19 в 11:12), всего редактировалось 1 раз
цитата
10/10/19 в 21:56
 Черный Корсар
Oswell E. Spencer писал:
Кстати, с каких пор рекламодатель, по OpenRTB куда-то запросы сам делает? icon_rolleyes.gif вообще ты в корне неправильно описал работу по openrtb, если что
Да, ошибся, партнерка отдает инфу реклу о таком то юзере, и рекл на своей стороне решает нужен он ему или нет. Ну тут тот же хуй, только вид сбоку icon_rolleyes.gif
цитата
10/10/19 в 22:06
 Oswell E. Spencer
По твоей логике, если норм что с одного сайта много пушей за раз приходит, то и попандеров на сайт надо по пять вешать, а баннеров и прероллов по 20 штук)

Вся суть же в чем, подписывая на кучу баз на одном сайте, вы все это делаете в одном рекламном споте сайта, так сказать, тем самым перегружая это рекламное место. Аналогия с пятью попандерами прямая, имхо. В итоге эффективность сводится к нулю, но да, за пару часов вы слизали бюджет рекла, все заработали "гору денег", кроме рекла)


никто же в здравом уме не вешает десятки баннеров на странице, не вешает несколько попандеров, не показывает несколько прероллов за раз, так а чем пуши то хуже?


p.s. Хотя я согласен, перед выдачей кода надо уточнять, что мол так и так, сносит все остальное нещщадно smail101.gif
цитата
10/10/19 в 22:29
 Oswell E. Spencer
А вот кстати еще, забыл. Ваш код вешали в дополнение к любому коду, любой партнерки, но наверно у той партнерки никто не спрашивал, что юзера еще куда-то пропихнули параллельно? Они наверно так рады были бы, что за них решили, за каких юзеров они платить должны, особенно если за выкуп платили icon_wink.gif
цитата
11/10/19 в 10:45
 Черный Корсар
Oswell E. Spencer писал:
за пару часов вы слизали бюджет рекла, все заработали "гору денег", кроме рекла)

Ты никогда не задумывался, почему реклы сливают тонны бюджета на покупку трафа? Наверное не из-за любви к искусству. Наверное они все же имеют с этого профит. Никто же в здравом уме не будет работать в минус? Или это не так? Или ты сам покупаешь рекламу только для того, что бы принести прибыль парнерке?


Oswell E. Spencer писал:
тем самым перегружая это рекламное место.

Рекламное место на сайте, это рекламное место на сайте Это ключевой момент. Вешая на туб 5 попандеров и 100500 баннеров ты его перегружаешь, да. Но это пуши, они приходят на устройства юзерам. Это 2 разные сущности.
Я повторюсь, кол-во отписок не зависит от кол-ва отправляемых пушей. Если юзер не хочет получать уведомления, то он откажется в любом случае, ты хоть по одному уведомлению в год ему пообещай.

Последний раз редактировалось: Черный Корсар (11/10/19 в 11:40), всего редактировалось 1 раз
цитата
11/10/19 в 10:48
 Черный Корсар
Oswell E. Spencer писал:
А вот кстати еще, забыл. Ваш код вешали в дополнение к любому коду, любой партнерки, но наверно у той партнерки никто не спрашивал, что юзера еще куда-то пропихнули параллельно? Они наверно так рады были бы, что за них решили, за каких юзеров они платить должны, особенно если за выкуп платили icon_wink.gif

Эту ответственность на себя полностью берет вебмастер. И он должен это осознавать ставя нас 2-ой партнеркой. И, я еще раз повторюсь, если кто то не хочет, что бы их юзали с кем то, пишите это в гайдах\термсах\топиках\каналах\рассылках. В общем - доносите это до своих партнеров. Пишите большим красным жирным шрифтом на странице получения скрипта
цитата
11/10/19 в 12:10
 Oswell E. Spencer
Черный Корсар писал:
. И, я еще раз повторюсь, если кто то не хочет, что бы их юзали с кем то, пишите это в гайдах\термсах\топиках\каналах\рассылках. В общем - доносите это до своих партнеров. Пишите большим красным жирным шрифтом на странице получения скрипта



Ну теперь то , благодаря шуму, только ленивый это в термсы не внесет, имхо icon_cool.gif

И будут банить без выплат, за такие финты, потому как ПП имхо это нафиг не нужно, большинству. А про ответственность вебмастеров перед первой ПП в вашем топике ни слова, кстати.


Эта страница в полной версии