Auto Skip Streaming Services

28/04/2024, 23:42:18 Clicar Automaticamente em "Pular Abertura" e em "Próximo Episódio" em diversas plataformas de streaming

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Auto Skip Streaming Services
// @namespace   Violentmonkey Scripts
// @match       https://www.disneyplus.com/*
// @match       https://www.starplus.com/*
// @match       https://www.max.com/*
// @match       https://www.netflix.com/*
// @grant       none
// @version     5.1
// @author      RedBlack
// @description 28/04/2024, 23:42:18 Clicar Automaticamente em "Pular Abertura" e em "Próximo Episódio" em diversas plataformas de streaming
// @license     0BSD
// ==/UserScript==

// Configuração inicial dos seletores de botões para cada plataforma
let config = {
  'DisneyPlus': {
    skipButton: ['button.skip__button.body-copy', 'class'],
    nextButton: ['button._5gjogg1', 'class']
  },
  'StarPlus': {
    skipButton: ['button.skip__button.body-copy', 'class'],
    nextButton: ['button._5gjogg1', 'class']
  },
  'Max': {
    skipButton: ['.skip-btn', 'class'],
    nextButton: ['.next-episode-btn', 'class']
  },
  'Netflix': {
    skipButton: ['.ltr-bf8b0m', 'class'],
    nextButton: ['button[data-uia="next-episode-seamless-button"]', 'attribute']
  }
};

// Velocidade de busca padrão
let searchInterval = 1000;

// Função para salvar as configurações no localStorage
function saveConfig() {
  localStorage.setItem('autoSkipConfig', JSON.stringify({
    config,
    searchInterval
  }));
}

// Carrega a configuração salva do localStorage
function loadConfig() {
  const config = localStorage.getItem('buttonConfig');
  if (config) {
    buttonConfig = JSON.parse(config);
  }
  else {
    buttonConfig = {}; // Certifique-se de que seja um objeto vazio
  }

  // Se não houver botões configurados, inicialize o objeto como um vazio
  if (!Object.keys(buttonConfig).length) {
    buttonConfig = {};
  }
}

// Função para verificar se o botão está visível na janela
function isButtonVisible(buttonSelector) {
  const button = document.querySelector(buttonSelector[0]);
  return button && button.offsetParent !== null;
}

// Função para clicar no botão quando estiver visível
function clickButton(buttonSelector) {
  const button = document.querySelector(buttonSelector[0]);
  if (button) {
    const buttonText = button.textContent || button.innerText; // Captura o texto do botão
    button.click(); // Clica no botão
    showNotification(`Botão clicado: ${buttonText}`); // Exibe notificação com o texto do botão
  }
}

// Função para mostrar uma notificação na tela
function showNotification(message) {
  const notification = document.createElement('div');
  notification.textContent = message;
  notification.style.position = 'fixed';
  notification.style.bottom = '20px';
  notification.style.right = '20px';
  notification.style.padding = '12px 20px';
  notification.style.backgroundColor = '#323232';
  notification.style.color = '#FFFFFF';
  notification.style.borderRadius = '8px';
  notification.style.boxShadow = '0px 4px 12px rgba(0, 0, 0, 0.2)';
  notification.style.fontSize = '14px';
  notification.style.fontFamily = 'Arial, sans-serif';
  notification.style.zIndex = '9999';
  notification.style.opacity = '0';
  notification.style.transition = 'opacity 0.5s ease';

  document.body.appendChild(notification);

  // Faz a notificação aparecer gradualmente
  setTimeout(() => (notification.style.opacity = '1'), 100);
  // Faz a notificação desaparecer após 2 segundos
  setTimeout(() => {
    notification.style.opacity = '0';
    setTimeout(() => notification.remove(), 500);
  }, 2000);
}

// Função para verificar e clicar nos botões configurados
function checkAndClickButtons() {
  const platform = detectPlatform();
  if (platform) {
    const {
      skipButton,
      nextButton
    } = config[platform];
    if (isButtonVisible(skipButton)) clickButton(skipButton);
    if (isButtonVisible(nextButton)) clickButton(nextButton);
  }
}

// Função para detectar a plataforma atual com base no URL
function detectPlatform() {
  const url = window.location.href;
  if (url.includes('disneyplus.com')) return 'DisneyPlus';
  if (url.includes('starplus.com')) return 'StarPlus';
  if (url.includes('max.com')) return 'Max';
  if (url.includes('netflix.com')) return 'Netflix';
  return null;
}

// Cria uma interface para configuração dos seletores
function createConfigInterface() {
  const configContainer = document.createElement('div');
  configContainer.style.position = 'fixed';
  configContainer.style.top = '50px';
  configContainer.style.right = '20px';
  configContainer.style.width = '300px';
  configContainer.style.maxHeight = '400px'; // Altura máxima para o contêiner
  configContainer.style.overflowY = 'auto'; // Habilita rolagem vertical
  configContainer.style.padding = '15px';
  configContainer.style.backgroundColor = '#1e1e1e'; // Cor de fundo escura
  configContainer.style.borderRadius = '8px';
  configContainer.style.boxShadow = '0px 4px 12px rgba(0, 0, 0, 0.3)';
  configContainer.style.zIndex = '10000';
  configContainer.style.display = 'none';
  configContainer.style.fontFamily = 'Arial, sans-serif';
  configContainer.style.color = '#FFFFFF'; // Cor do texto

  // Cabeçalho do painel de configuração
  const header = document.createElement('h3');
  header.textContent = 'Configurações de Seletores';
  header.style.marginBottom = '10px';
  header.style.color = '#FFFFFF'; // Cor do cabeçalho
  configContainer.appendChild(header);

  // Cria entradas para cada plataforma
  for (const [platform, selectors] of Object.entries(config)) {
    const platformLabel = document.createElement('h4');
    platformLabel.textContent = platform;
    platformLabel.style.color = '#FFDD57'; // Cor para o nome da plataforma
    configContainer.appendChild(platformLabel);

    Object.keys(selectors).forEach((buttonType) => {
      const label = document.createElement('label');
      label.textContent = `${buttonType}: `;
      label.style.display = 'block';
      label.style.margin = '5px 0';
      label.style.color = '#FFFFFF'; // Cor do texto do label

      // Campo de entrada para o seletor
      const input = document.createElement('input');
      input.type = 'text';
      input.value = selectors[buttonType][0];
      input.style.width = '60%';
      input.style.padding = '6px';
      input.style.marginBottom = '10px';
      input.style.border = 'none';
      input.style.borderRadius = '4px';
      input.style.backgroundColor = '#2e2e2e'; // Cor de fundo do input
      input.style.color = '#FFFFFF'; // Cor do texto do input
      input.onchange = () => {
        selectors[buttonType][0] = input.value;
        saveConfig();
      };

      // Select para tipo de seletor (class, id, attribute)
      const select = document.createElement('select');
      select.style.marginLeft = '5px';
      select.style.padding = '6px';
      select.style.borderRadius = '4px';
      select.style.backgroundColor = '#2e2e2e'; // Cor de fundo do select
      select.style.color = '#FFFFFF'; // Cor do texto do select
      const optionClass = new Option('Class', 'class', false, selectors[buttonType][1] === 'class');
      const optionId = new Option('ID', 'id', false, selectors[buttonType][1] === 'id');
      const optionAttribute = new Option('Attribute', 'attribute', false, selectors[buttonType][1] === 'attribute');
      select.add(optionClass);
      select.add(optionId);
      select.add(optionAttribute);
      select.onchange = () => {
        selectors[buttonType][1] = select.value;
        saveConfig();
      };

      // Botão de excluir seletor
      const deleteButton = document.createElement('button');
      deleteButton.textContent = 'X';
      deleteButton.style.padding = '6px 10px';
      deleteButton.style.backgroundColor = '#FF5722'; // Cor de fundo do botão de excluir
      deleteButton.style.color = '#FFF';
      deleteButton.style.border = 'none';
      deleteButton.style.borderRadius = '4px';
      deleteButton.style.cursor = 'pointer';
      deleteButton.style.marginLeft = '10px';
      deleteButton.onclick = () => {
        delete selectors[buttonType]; // Remove o seletor
        saveConfig();
        window.location.reload(); // Recarrega a página para aplicar mudanças
      };

      label.appendChild(input);
      label.appendChild(select);
      label.appendChild(deleteButton);
      configContainer.appendChild(label);
    });
  }

  // Cria campo de entrada para a velocidade de busca
  const speedLabel = document.createElement('label');
  speedLabel.textContent = 'Velocidade de busca (ms): ';
  speedLabel.style.display = 'block';
  speedLabel.style.marginTop = '10px';
  speedLabel.style.color = '#FFFFFF'; // Cor do texto do label

  const speedInput = document.createElement('input');
  speedInput.type = 'number';
  speedInput.value = searchInterval;
  speedInput.style.width = '60%';
  speedInput.style.padding = '6px';
  speedInput.style.marginBottom = '10px';
  speedInput.style.border = 'none';
  speedInput.style.borderRadius = '4px';
  speedInput.style.backgroundColor = '#2e2e2e'; // Cor de fundo do input
  speedInput.style.color = '#FFFFFF'; // Cor do texto do input
  speedInput.onchange = () => {
    searchInterval = parseInt(speedInput.value, 10);
    saveConfig();
  };

  configContainer.appendChild(speedLabel);
  configContainer.appendChild(speedInput);

  // Botão para abrir/fechar o painel de configuração
  const toggleConfigButton = document.createElement('button');
  toggleConfigButton.textContent = 'Configurações';
  toggleConfigButton.style.position = 'absolute';
  toggleConfigButton.style.top = '10px';
  toggleConfigButton.style.right = '20px';
  toggleConfigButton.style.padding = '10px';
  toggleConfigButton.style.backgroundColor = '#007BFF';
  toggleConfigButton.style.color = '#FFF';
  toggleConfigButton.style.border = 'none';
  toggleConfigButton.style.borderRadius = '4px';
  toggleConfigButton.style.cursor = 'pointer';
  toggleConfigButton.onclick = () => {
    configContainer.style.display = configContainer.style.display === 'none' ? 'block' : 'none';
  };

  document.body.appendChild(toggleConfigButton);
  document.body.appendChild(configContainer);
}

// Carrega a configuração ao iniciar
loadConfig();
createConfigInterface();

// Inicia a verificação dos botões a cada intervalo de busca
setInterval(checkAndClickButtons, searchInterval);