Omegle Grabber

Get IP addresses on multiple video chat sites

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name        Omegle Grabber
// @description Get IP addresses on multiple video chat sites
// @version     0.7.0
// @author      Adam Thompson-Sharpe
// @namespace   MysteryBlokHed
// @license     GPL-3.0
// @copyright   2022 Adam Thomspon-Sharpe
// @homepageURL https://gitlab.com/MysteryBlokHed/userscripts/-/tree/main/OmegleGrabber
// @supportURL  https://gitlab.com/MysteryBlokHed/userscripts/-/issues
// @match       *://*.omegle.com/*
// @match       *://*.ome.tv/*
// @match       *://*.chathub.cam/*
// @match       *://*.emeraldchat.com/*
// @match       *://*.camsurf.com/*
// @match       *://*.strangercam.com/*
// @match       *://*.allotalk.com/*
// @require     https://greasyfork.org/scripts/440463-greasetools/code/greasetools.js?version=1021292
// @grant       GM.xmlHttpRequest
// ==/UserScript==
/// <reference types="greasetools" />
;(() => {
  const { xhrPromise } = GreaseTools
  const SiteMap = {
    'www.omegle.com': 'omegle',
    'ome.tv': 'ometv',
    'chathub.cam': 'chathub',
    'www.emeraldchat.com': 'emeraldchat',
    'camsurf.com': 'camsurf',
    'strangercam.com': 'strangerOrAllo',
    'app.strangercam.com': 'strangerOrAllo',
    'randomchat.allotalk.com': 'strangerOrAllo',
  }
  let currentIp = 'Not Found'
  const srflxIp = candidate => {
    var _a
    if (!candidate.candidate || !candidate.candidate.includes('typ srflx'))
      return null
    const addresses = candidate.candidate.match(
      /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g,
    )
    return addresses
      ? (_a = addresses[0]) !== null && _a !== void 0
        ? _a
        : null
      : null
  }
  const removeWhenExists = getEl => {
    const interval = setInterval(() => {
      const el = getEl()
      if (el) {
        el.remove()
        clearInterval(interval)
      }
    }, 500)
  }
  const Sites = {
    omegle: {
      getIp: srflxIp,
      onload() {
        removeWhenExists(() => document.querySelector('#videologo'))
      },
      addIpInfo(message) {
        const chatbox = document.querySelector('.logbox .logitem')
        if (!chatbox) return
        chatbox.innerText = message
      },
    },
    ometv: {
      lastCandidateType: 'relay',
      onload() {
        removeWhenExists(() =>
          document.querySelector('.remote-video__watermark'),
        )
      },
      getIp(candidate) {
        const lastCandidateType = this.lastCandidateType
        this.lastCandidateType = candidate.type
        if (candidate.type === 'relay' && lastCandidateType !== 'relay')
          return candidate.address
        return null
      },
      addIpInfo(message) {
        const chat = document.querySelector('.message.system')
        if (!chat) return
        const messageContainer = document.createElement('div')
        messageContainer.className = 'message in'
        messageContainer.style.textAlign = 'center'
        const messageEl = document.createElement('span')
        messageEl.innerText = message
        messageContainer.appendChild(messageEl)
        chat.prepend(messageContainer)
      },
    },
    chathub: {
      getIp: srflxIp,
      addIpInfo(message) {
        const chatbox = document.querySelector('#message-section')
        if (!chatbox) return
        const messageEl = document.createElement('p')
        messageEl.style.textAlign = 'center'
        messageEl.innerText = message
        chatbox.prepend(messageEl)
      },
    },
    emeraldchat: {
      getIp: srflxIp,
      addIpInfo(message) {
        if (!this.ipInfoEl) {
          const chatbox = document.querySelector('#messages')
          if (!chatbox) return
          this.ipInfoEl = document.createElement('p')
          this.ipInfoEl.style.textAlign = 'center'
          chatbox.prepend(this.ipInfoEl)
        }
        this.ipInfoEl.innerText = message
      },
      rtcClose() {
        this.addIpInfo(currentIp)
      },
    },
    camsurf: {
      getIp: srflxIp,
      addIpInfo(message) {
        const chatbox = document.querySelector('.rv_head.chat-ava > p')
        console.log(chatbox)
        if (!chatbox) return
        chatbox.innerText = message
      },
    },
    strangerOrAllo: {
      getIp: srflxIp,
      addIpInfo(message) {
        const chatBody = document.querySelector('.chat-body')
        if (!chatBody) return
        const remoteChat = document.createElement('div')
        remoteChat.className = 'remote-chat'
        const container = document.createElement('div')
        const ipInfo = document.createElement('span')
        ipInfo.className = 'server-msg'
        ipInfo.innerText = message
        container.appendChild(ipInfo)
        remoteChat.appendChild(container)
        chatBody.prepend(remoteChat)
      },
    },
  }
  /**
   * Get the active site
   * @returns The active site
   * @throws {Error} Thrown if an unsupported site is visited
   */
  const getSite = () => {
    if (location.hostname in SiteMap) return SiteMap[location.hostname]
    throw new Error(`Activated on unsupported site (${location.hostname})`)
  }
  /** The active site */
  const site = getSite()
  window.addEventListener('load', () => {
    var _a, _b
    return (_b = (_a = Sites[site]).onload) === null || _b === void 0
      ? void 0
      : _b.call(_a)
  })
  /** Some sites hijack most logging functions, but they tend to forget about groups */
  const groupLog = (...data) => {
    console.groupCollapsed(...data)
    console.groupEnd()
  }
  /**
   * @param code A two-letter country code
   * @returns A Promise that resolves with the country's full name and its flag emoji,
   * or rejects with the message returned by the API in case of failure
   */
  const fullCountry = code =>
    new Promise(async (resolve, reject) => {
      const result = await fetch(
        `https://restcountries.com/v3.1/alpha/${code.toUpperCase()}`,
      )
      const response = JSON.parse(await result.text())[0]
      if (result.status !== 200) reject(response.text)
      resolve(
        `${response.name.common} ${response.flag} (${code.toUpperCase()})`,
      )
    })
  /** Look up ip info */
  const findIpInfo = ip =>
    new Promise(resolve => {
      xhrPromise({
        method: 'GET',
        url: `https://ipinfo.io/${ip}/json`,
      })
        .then(async ({ responseText }) => {
          const info = JSON.parse(responseText)
          resolve({
            ip,
            country: await fullCountry(info.country).catch(() => info.country),
            region: info.region,
            city: info.city,
            org: info.org,
            loc: info.loc,
            tz: info.timezone,
          })
        })
        .catch(() => {
          groupLog('Failed to get IP info from ipinfo.io')
          resolve({ ip })
        })
    })
  const defaultInfo = ({ ip, country, region, city, org, loc, tz }) => {
    return {
      ip,
      country: country !== null && country !== void 0 ? country : 'Not Found',
      region: region !== null && region !== void 0 ? region : 'Not Found',
      city: city !== null && city !== void 0 ? city : 'Not Found',
      org: org !== null && org !== void 0 ? org : 'Not Found',
      loc: loc !== null && loc !== void 0 ? loc : 'Not Found',
      tz: tz !== null && tz !== void 0 ? tz : 'Not Found',
    }
  }
  const getTime = timeZone => new Date().toLocaleString('en-US', { timeZone })
  /** Add IP info to the chatbox */
  const addIpInfo = info => {
    const { ip, country, region, city, org, loc, tz } = defaultInfo(info)
    Sites[site].addIpInfo(`\
IP: ${ip}
Country: ${country}
Region: ${region}
City: ${city}
Org: ${org}
APPROX Coords: ${loc}
Timezone: ${tz}
Time (When First Connected): ${getTime(tz)}
\n`)
  }
  /**
   * Proxy handler for the RTCPeerConnection.prototype.addIceCandidate function
   */
  const addIceCandidateHandler = {
    apply(target, thisArg, args) {
      const candidate = args[0]
      console.groupCollapsed('Candidate', candidate, 'added')
      groupLog('Type:\t\t', candidate.type)
      groupLog('Address:\t', candidate.address)
      groupLog('Related:\t', candidate.relatedAddress)
      console.groupEnd()
      const ip = Sites[site].getIp(candidate)
      if (ip && ip !== currentIp) {
        currentIp = ip
        groupLog('IP FOUND:', currentIp)
        findIpInfo(currentIp).then(info => {
          groupLog('IP INFO:', info)
          addIpInfo(info)
        })
      }
      return Reflect.apply(target, thisArg, args)
    },
  }
  /**
   * Proxy handler for the RTCPeerConnection.prototype.close function
   */
  const closeHandler = {
    apply(target, thisArg, args) {
      var _a, _b
      currentIp = 'Not Found'
      // Call rtcClose if defined
      ;(_b = (_a = Sites[site]).rtcClose) === null || _b === void 0
        ? void 0
        : _b.call(_a)
      return Reflect.apply(target, thisArg, args)
    },
  }
  RTCPeerConnection.prototype.addIceCandidate = new Proxy(
    RTCPeerConnection.prototype.addIceCandidate,
    addIceCandidateHandler,
  )
  RTCPeerConnection.prototype.close = new Proxy(
    RTCPeerConnection.prototype.close,
    closeHandler,
  )
})()