您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Делает интерфейс Фотостраны более удобным
// ==UserScript== // @name Fotostrana Pet Interface // @namespace scriptomatika // @description Делает интерфейс Фотостраны более удобным // @include http*://*fotostrana.ru/pet* // @include http*://*fotostrana.ru/app* // @include http*://*fotostrana.ru/finance* // @include http*://*fotostrana.ru/sports* // @require https://gf.qytechs.cn/scripts/379902-include-tools/code/Include%20Tools.js // @require https://gf.qytechs.cn/scripts/389814-fotostrana-sports/code/Fotostrana%20Sports.js // @noframes // @icon http://userscripts.scriptomatika.ru/icon/favicon-389815.png // @author mouse-karaganda // @version 1.9 // @grant none // ==/UserScript== (function(unsafeWindow) { if (unsafeWindow.self != unsafeWindow.top) return; var console = unsafeWindow.console; var $$ = unsafeWindow.__krokodil; var $ = unsafeWindow.jQuery; console.log('💬 Фотострана пришла! pet'); if (!unsafeWindow.$fotostrana) { unsafeWindow.$fotostrana = {}; } $$.extend(unsafeWindow.$fotostrana, { /** * Определим, что мы находимся на страничке питомца */ isPetPage: function() { return /\.ru\/pet/i.test(location.href); } /** * Определим, что мы находимся на страничке финансов */ , isFinancePage: function() { return /\.ru\/finance/i.test(location.href); } /** * Стили для новых объектов */ , style: function() { $$.renderStyle( '.finroom-balance-bonus { margin-left: 16px; }', //'.petBubble.petBottomNavBubble .bubbleIco.icoFant { background-position: -7px -7px; background-image: url(//a1.s.fsimg.ru/app/fs2pet/img/ru_fant48.png); }', '.petBubble.petBottomNavBubble .bubbleIco.miscIco { background-image: url(//a1.s7.fsimg.ru/app/fs2pet/img/misc.png); }', '.petBubble.petBottomNavBubble .miscIco.icoGift { background-position: -89px -2px; }', '.petBubble.petBottomNavBubble .miscIco.icoFant { background-position: -65px 0px; }', '.icoSize24 { width: 24px; height: 24px; }', '.icoSize35 { width: 35px; height: 35px; }', '#petGuestFriend .ownerContestLink { display: none; }', '#petGuestFriend:hover .ownerContestLink { display: inline; }', '.ownerContestLink { position: absolute; top: 36px; right: -14px; }', '.ownerContestLink img { border-radius: 3px; border: 1px solid #21A0D1; background-color: #FFFDFF; padding: 1px; }', '.ownerContestLink:hover img { border-color: #F1592B; }' ); } /** * Взять ежедневный бонус в комнате финансов */ , financeDailyBonus: function() { if (!this.isFinancePage()) return; // Создадим кнопку для однокликовой комбинации var moreButton = ('#finroom-promos .finroom-block-more'); $('<a class="finroom-balance-bonus" />') .text('Бонус за посещение') .attr({ href: '#' }) .insertAfter(moreButton) .click(function(e) { e.preventDefault(); $(moreButton).trigger('click'); $fotostrana.missingElement('.iPopup .finroom-promo-daily-btn', function(exists) { if (exists) { // Появилась кнопка с бонусом — кликаем $(this).trigger('click'); $fotostrana.missingElement('.iPopup .finroom-daily-bonus-prize-btn', function(exists) { if (!exists) return; $(this).trigger('click'); $fotostrana.missingElement('.iPopup .finroom-daily-bonus-popup-close', function(exists) { if (!exists) return; $(this).trigger('click'); $fotostrana.missingElement('.iPopup .popup-header .icn-cross', function(exists) { if (!exists) return; $(this).trigger('click'); }); }); }); } else { // Кнопка с бонусом не появилась $('.iPopup .popup-header .icn-cross').trigger('click'); } }); }); } /** * Взять ежедневный бонус в доме питомца */ , petDailyBonus: function() { if (!this.isPetPage()) return; // В течение 3 минут проверяем, что есть значок бонуса $fotostrana.missingElement('#dailyBonusIco', function(exists) { if (!exists) return; $(this).trigger('click'); // ждем окно с кнопкой $fotostrana.missingElement('#bonusDayButton', function(exists) { if (!exists) return; // Появилась кнопка с бонусом — кликаем и сразу закрываем $(this).trigger('click'); $fotostrana.missingElement('#popup.bonusDay .popupClose', function(exists) { $(this).trigger('click'); }); }); }); } /** * Имя питомца и его владельца */ , petOwnerName: function() { if (!this.isPetPage()) return; // Извлечем имя питомца и его владельца var extractNames = function() { if (!APP.currentPet) return; // Имя питомца var petName = APP.currentPet.name; // Имя владельца var ownerName = APP.currentPet.ownerName; if (!petName || !ownerName) return; petName = $$.format('{0} и {1}', ownerName, petName); document.title = $$.format('{0} - {1} - @', petName, document.title); }; // Ссылка на голосование для владельца var contestLink = function() { if (!APP.currentPet) return; // ID владельца var ownerId = APP.currentPet.ownerId; if (!ownerId) return; // Ищем блок владельца var petUserImg = $('#petGuestFriend').find('.petUserImg'); if (petUserImg.length == 0) return; // Ищем ссылку на голосование var ownerContestLink = $('#petGuestFriend').find('.ownerContestLink'); // Предотвращаем дублирование if (ownerContestLink.length > 0) return; // Создаем ссылку на голосование $('<a />').insertAfter(petUserImg) .addClass('ownerContestLink') .bindHelpTooltip('Голосование') .attr({ href: ('/contest/' + ownerId), target: '_blank' }) .each(function(index, elem) { $('<img />').appendTo(this) .attr({ alt: 'vote', src: ('//i02.fotocdn.net/6/app_favicon/6/6805.jpg') }) }); }; var getNames = function() { // Проверим, не было ли изменено заглавие ранее if (!/- @$/.test(document.title)) { extractNames(); } // Ссылка на голосование для владельца contestLink(); }; getNames(); setInterval(getNames, 1000); } /** * Скрыть все периферийные элементы */ , hideBackground: function() { /* $fotostrana.missingElement('#header a.link-text[href*="/rating/"]', function() { var link = $(this); var showState = !link.data('showState'); link.data('showState', showState); if (showState) link.text('Выключить фон') .unbind('click').bind('click', function() { $('#logo-wrap') .add('#photocontest-link') .add('#header .link-text') .add('#header .link-ico') .add('#header .profile-link') .add('#season-centered-box') .add('#header-add-pin') .add('#activity-rating-counter') .add('#inviteUserBlock') .add('#notifiers-wrap') .add('#tickersHomeWrap') .add('.petFriendsListWrap .petUserImg img') .add('#flPetHome') .add('#petToSeasonHomeIco') // вопрос .add('#homeDoorHalloween') .add('#petHome #homeScrollPrev') .add('#petHome #homeScrollNext') .add('#petNewHomeBottomBanner') .add('#questIconsList') .add('#petBlock .phrase') .add('#petBlock .thinkBalloon') .softHide() //.css('visibility', 'visible') $('#footer.pet_footer') .add('#petTopNavigationContainer') .add('#bottomPanelEvents') .hide(); $('#petAreaWrap') .css({ marginTop: 0 }) $('#header a.link-text[href*="people"]') .css('visibility', 'visible'); $('#petBlock .image') .show(); }); } }*/ } /** * Автокликер для дома (набираем опыт на бесплатных действиях) */ , autoActions: function() { if (!this.isPetPage()) return; $fotostrana.missingElement('#petActionsPanel .petActionsList', function(exists) { if (!exists) return; // Определим максимум шагов таймера на этот раз var appendStep = Math.trunc(Math.random() * 20) + 1; // Назначим кнопку для включения таймера var petActionsList = $(this); var itemTimer = $fotostrana.itemTimer(); itemTimer.text('Таймер') .data({ timerState: false, title: 'Включить таймер', ico: -1, step: 0, maxStep: 40 + appendStep }) //.bindHelpTooltip($(this).data('title')) .hover(function(e) { delete this.tooltip; helpTooltip.show(this, $(this).data('title')); }, function(e) { helpTooltip.hide(this); }) .unbind('click').bind('click', function(e) { e.preventDefault(); $fotostrana.toggleAutoTimer(petActionsList); }); // Проверим, задано ли автоматическое включение таймера var storageKey = ('autoActionsRestart.' + itemTimer.data('petId')); if ($$.isString(localStorage[storageKey])) { localStorage.removeItem(storageKey); setTimeout(function() { $fotostrana.toggleAutoTimer(petActionsList); }, 5000); } }); } /** * Пункт меню, содержащий таймер */ , itemTimer: function() { var petId = location.href.match(/\/pet\/(\d+)/)[1]; return $('#header .link-text[href*="people"]') .data({ petId: petId }); } /** * Включим или выключим таймер для автоматических действий */ , toggleAutoTimer: function(petActionsList) { // Распределим группы параметров var setGroupData = function() { petActionsList.find('li.petActionsItem') .each(function() { // Найдем вид параметра var groupId = '#' + $(this).attr('id'); // Найдем идентификатор группы внутри модуля var home = APP.module('home').home; var groupIndex = $$.each(home.operationGroups, function(elem, index, source) { if (elem.selector == groupId) return true; }); $(this).data({ groupId: groupId, groupIndex: groupIndex }); }); }; // Манипулируем состоянием пункта меню var itemTimer = $fotostrana.itemTimer(); var timerState = !itemTimer.data('timerState'); itemTimer.data('timerState', timerState); if (timerState) { // Включим таймер автоклика itemTimer.text('Таймер').data({ title: 'Выключить таймер' }) .css({ color: 'yellow' }); // Скроем flash-ролик дома $('#flPetHome').softHide(); // Скроем баннеры в доме $('div[id$="Banner"], div[class$="Banner"]') // Скроем навигацию по приложениям .add('#petTopNavigationContainer') .hide(); setGroupData(); $fotostrana.findAvailableAction(); $fotostrana.autoActionsTimer = setInterval($fotostrana.findAvailableAction, 10000); } else { // остановим таймер itemTimer.text('Таймер').data({ title: 'Включить таймер'}) .css({ color: '' }); // Вновь покажем flash-ролик дома $('#flPetHome').css({ visibility: '' }); // Покажем баннеры в доме $('div[id$="Banner"], div[class$="Banner"]') // Скроем навигацию по приложениям .add('#petTopNavigationContainer') .show(); clearInterval($fotostrana.autoActionsTimer); console.warn('Таймер выключен'); } // Сменим подсказку helpTooltip.hide(itemTimer.get(0)); //itemTimer.trigger('mouseover'); } /** * Ищем доступные бесплатные действия */ , findAvailableAction: function() { // Проведем мышкой над упавшими бонусами $('#homeInterface .paramsVisual').trigger('mouseover'); // Откроем действия, если мы в гостевом домике $('#petActionsPanel .petActionsTabs').find('.petActions.off') .trigger('click'); // Закроем всплывающее окно, если открыто $('#popup:visible').find('.popupClose') .trigger('click'); // Закроем вспомогательные окошки $('#petBlock .thinkBalloon') .add('#petBlock .phrase') .softHide(); // Подключаемся к модулю var home = APP.module('home').home; // Критерии поиска var search = { // Берем только бесплатные notPrice: function(index, elem) { // Берем только бесплатные //var price = $(this).children('.price.coins'); var price = $(this).children('.price'); return price.length == 0; }, // Запомним данные об операции setOperationData: function(groupIndex) { return function() { var opNode = $(this).find('.ico'); // Отыскиваем текущую операцию в модуле var homeOp = null; try { homeOp = home.operations[groupIndex]; } catch (ex) { } if (!homeOp) { // Выключим таймер (и перезагрузим ?) return; } var opIndex = $$.each(homeOp, function(elem, index, source) { if (opNode.hasClass(elem.css_class)) return true; }); var oneOp = null; try { oneOp = homeOp[opIndex]; } catch (ex) { } if (!oneOp) return; //console.log('oneOp RESULT: %o', oneOp); // Переписываем некоторые сведения об отдельной операции из модуля $(this).data({ selector: home.operationGroups[groupIndex].selector, name: oneOp.name, title: oneOp.title, time: oneOp.time, exp: oneOp.opt_general, // опыт health: oneOp.opt_health, happy: oneOp.opt_joy, satiety: oneOp.opt_hunger, clean: oneOp.opt_clear }); //console.log('oneOp DATA: %o', $(this).data()); }; }, // Определим, даст ли действие максимальную продуктивность findMaxCapacity: function() { var data = $(this).data(); // 1) Найдем все плюсовые и минусовые действия var plusOp = [], minusOp = [], groups = ['health', 'happy', 'satiety', 'clean'], values = {}; $$.each(groups, function(elem) { if (data[elem] > 0) { plusOp.push(elem); } else if (data[elem] < 0) { minusOp.push(elem); } }); //console.info('findMaxCapacity [%o / %o]: plusOp == %o, minusOp == %o', data.selector, data.name, plusOp, minusOp); // 2) Найдем текущие значения всех параметров $('#petHealth, #petHappy, #petSatiety, #petClean') .each(function() { var groupNode = $(this); // Сначала определим название группы var groupIndex = $$.each(groups, function(elem, index, source) { if (groupNode.hasClass(elem)) return true; }); // Извлечем и запомним значение var groupValue = groupNode.find('.petActionsGroupValue').text(); groupValue = parseInt($.trim(groupValue)); var paramName = groups[groupIndex]; var plusVal; values[paramName] = { val: groupValue, plus: (plusVal = data[paramName]) > 0 ? plusVal : 0 }; }); //console.info('findMax [%s/%s]: %o, values == %o', data.selector, data.name, data.title, values); // 3) Разрешим действие, если хотя бы один из плюсовых параметров меньше локального максимума var maximum = 100, plusResult = false, minusResult = false; $$.each(plusOp, function(elem, index, source) { // Локальный максимум - это шаг, который нужно сделать данным действием, // чтобы в следующую (а не в текущую) итерацию получить максимум var localMaximum = (maximum - values[elem].plus); plusResult = plusResult || (values[elem].val <= localMaximum); }); // 4) Если все плюсовые параметры на максимуме, то // запретим действие, если хотя бы один из минусовых параметров меньше максимума if (!plusResult) { $$.each(minusOp, function(elem, index, source) { minusResult = minusResult || (values[elem].val < maximum); }); } var result = plusResult || !minusResult; console.info('findMax [%s/%s]: %o, values == %o, result == %o', data.selector, data.name, data.title, values, {plus: plusResult, minus: minusResult, res: result}); return result; }, // Автоматическая перезагрузка cronAutomaticRestart: function() { var itemTimer = $fotostrana.itemTimer(); var nextStep = itemTimer.data('step') + 1; var maxStep = itemTimer.data('maxStep'); itemTimer.data('step', nextStep); // Остановим таймер и перезагрузим if (nextStep >= maxStep) { $fotostrana.toggleAutoTimer(); var storageKey = ('autoActionsRestart.' + itemTimer.data('petId')); localStorage.setItem(storageKey, true); location.replace(location.href); }; }, // Логи и надпись в зависимости от того, есть ли доступные действия renderTimerInfo: function(actionCount) { var doConsole = (actionCount > 0) ? 'info' : 'log'; console[doConsole]('Доступно действий: %o', actionCount); // Определим, какую картинку показать var icoChar = '|/-\\|/-\\'; var itemTimer = $fotostrana.itemTimer(); var nextIco = itemTimer.data('ico') + 1; if (nextIco >= icoChar.length) { nextIco = 0; } var maxStep = itemTimer.data('maxStep'); var timerText = $$.template('Таймер {ico} {current} из {max}', { ico: icoChar[nextIco], current: maxStep - itemTimer.data('step') + 1, max: maxStep }); itemTimer.text(timerText).data('ico', nextIco); // Выделим цветом, если есть действие var timerColor = (actionCount > 0) ? 'lime' : 'yellow'; itemTimer.css({ color: timerColor }); } }; var actionCount = 0; // Найдем виды параметров var actions = $('#petActionsPanel .petActionsList') .find('li.petActionsItem') .reverse() .each(function() { // Найдем вид параметра var groupId = $(this).data('groupId'); // Найдем значение параметра var groupValue = $(this).find('.petActionsGroupValue').text(); groupValue = parseInt($.trim(groupValue)); // Найдеи индекс группы внутри модуля var groupIndex = $(this).data('groupIndex'); // Найдем доступные бесплатные действия var operations = $(this).find('div[id^="operationGroup"] li:not(.unavailable)') .filter(search.notPrice) // Для каждого действия находим, какие параметры и как оно изменяет .each(search.setOperationData(groupIndex)) // Выберем только те из них, которые дадут максимальную продуктивность .filter(search.findMaxCapacity); //console.log('Действие %o == %o, группа == %o, бесплатные == %o', groupId, groupValue, groupIndex, operations); // Выполняем первое действие из найденных (бесплатное, доступное, продуктивное) if (operations.length > 0) { actionCount = 1; operations.eq(0).trigger('click'); return false; } }); search.cronAutomaticRestart(); search.renderTimerInfo(actionCount); //APP.animation.config - все возможные действия } /** * Быстрые настройки в доме питомца */ , petQuickSettings: function() { if (!this.isPetPage()) return; $fotostrana.missingElement('#petMoneyAndOptions', function(exists) { if (!exists) return; // Создадим кнопку для быстрых настроек var quickSettings = $('<div />').prependTo(this) .attr({ id: 'petQuickSettings' }) .addClass('fl-l'); var btnSettings = $('<div />').appendTo(quickSettings) .addClass('petNavigationButton small') .click(function(e) { // Кликаем по кнопке настроек $('#petOptionsToggle').toggle('mouseenter'); // Ждём появления кнопки настроек $fotostrana.missingElement('.petOptionsWrap #settingsLink', function(exists) { if (!exists) return; //$(this).toggle('click'); // Ждем появления окна с настройками $fotostrana.missingElement('#popup.popupSettings', function(exists) { if (!exists) return; // Если сервисные зоны включены, отключим их $('#petServiceZonesCheckbox:not(:checked)').parent('label').toggle('click'); }); }); }); var icoSettings = $('<i />').appendTo(btnSettings) .addClass('petButtonSmallIco petOptionsItem icoSize20 icoPos9'); }); } /** * Подарки друзьям в доме питомца */ , giftsInPetWorld: function() { if (!this.isPetPage()) return; $fotostrana.missingElement('.petBubble.petWorld', function(exists) { if (!exists) return; var list = $(this).find('.content ul'); // Добавим кнопку для раздачи ключей в подарках $('<a href="?gifts=key" />').prependTo(list) .wrap('<li class="item fl-l" />') .append('<em class="bubbleIco icoSize28 miscIco icoGift" />') .tooltip({ tooltipExt: false, extraClass: 'simpleTooltip', content: 'Подарить ключи друзьям' }) .click($fotostrana.sendKeyGift); // Добавим кнопку для ежедневного бонуса var bonusBtn = $('#dailyBonusIco'); if (bonusBtn.length > 0) { $('<a href="?bonus=daily" />').prependTo(list) .wrap('<li class="item fl-l" />') .append('<em class="bubbleIco icoSize24 miscIco icoFant" />') //.append('<em class="bubbleIco icoSize35 icoFant" />') .tooltip({ tooltipExt: false, extraClass: 'simpleTooltip', content: 'Ежедневный бонус' }) .click(function(e) { e.preventDefault(); $fotostrana.petDailyBonus(); }); // Скроем вип-клуб list.find('li#vip').hide(); } }); } /** * Отослать ключ в подарок через интерфейс */ , sendKeyGift: function(e) { if (!!e && e.preventDefault) { e.preventDefault(); } // Отыщем первого друга, у кого есть значок подарка var friendWithGift = $('.petFriendsListWrap .petFriendsItem .giftBlock'); if (friendWithGift.length == 0) { // Прокрутим и вернемся позже console.warn('Нет друга с подарком'); $('.petFriendsContainer .scrollArrow.right').trigger('click'); setTimeout($fotostrana.sendKeyGift, 2000); return; } console.warn('Есть друг с подарком'); friendWithGift.eq(0).trigger('click'); $fotostrana.missingElement('#popup.notActivePetsGifts', function(exists) { if (!exists) return; // Если нет подарков - сразу отключаемся if ($(this).is('.noGift')) return; console.log('Найдено окно notActivePetsGifts'); // Найдем пункт с ключиком var keyItem = $(this).find('.giftList li') .filter(function(index, elem) { var span = $(this).find('span').css('backgroundImage'); return /gifts\/key/i.test(span); }); console.log('Найден ключ giftList li == %o', keyItem.find('span').eq(0)); setTimeout($$.createDelegate($fotostrana.doKeyGift, keyItem), 200); }); } /** * Непосредственно отправка ключа в подарок */ , doKeyGift: function() { $(this).eq(0).trigger('click'); // Отправим ключ другу $('#popup.notActivePetsGifts').find('.giftsWrap .buttons .btnSend') .trigger('click'); $fotostrana.missingElement('#popup.friendsGiftRequest', function(exists) { if (!exists) return; // Определим, где располагается ключ var keyItem = $(this).find('.requestObjectScrollContainer img[src*="gifts/key"]').parent('div'); var keyPosition = $(this).find('.requestObjectScrollContainer div').index(keyItem); // Найдем ширину, на которую нужно подвинуть ленту var keyWidth = keyItem.width() * keyPosition; // Жмем на кнопку, пока не отмотаем нужную ширину var _this = this; var keyTimer = -1; var keyHandler = function() { var currentLeft = $(_this).find('.requestObjectScrollContainer').css('left'); currentLeft = Math.abs(parseInt(currentLeft)); if (currentLeft >= keyWidth) { // Отодвинулись на нужную ширину - больше не надо кликать clearInterval(keyTimer); // Отправляем ключ дальше setTimeout($$.createDelegate(function() { $(this).find('.requestsSendButton .button.sendAll').trigger('click'); }, _this), 200); } else { // Если ключ ещё не показался, кликаем дальше $(_this).find('.scrollArrow.right').trigger('click'); } }; keyHandler(); keyTimer = setInterval(keyHandler, 800); }); } /** * Запустим систему в работу */ , startPet: function() { this.style(); this.financeDailyBonus(); this.petOwnerName(); this.petQuickSettings(); this.autoActions(); this.giftsInPetWorld(); } }); unsafeWindow.$fotostrana.startPet(); })(paramWindow);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址