feat: dns over http

fix: repeating badge color
fix: w2g url
This commit is contained in:
ThaUnknown 2023-05-24 20:42:53 +02:00
parent 2d3013e226
commit 4da3254493
7 changed files with 170 additions and 174 deletions

View file

@ -1,6 +1,6 @@
{
"name": "Miru",
"version": "3.10.5",
"version": "3.10.6",
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
"description": "Stream anime torrents, real-time with no waiting for downloads.",
"main": "src/index.js",

View file

@ -108,6 +108,13 @@ ipcMain.on('devtools', () => {
webtorrentWindow.webContents.openDevTools()
})
ipcMain.on('doh', (event, dns) => {
app.configureHostResolver({
secureDnsMode: 'secure',
secureDnsServers: [dns]
})
})
function createWindow () {
// Create the browser window.
webtorrentWindow = new BrowserWindow({

View file

@ -14,7 +14,7 @@
PLANNING: 'rgb(247,154,99)',
COMPLETED: 'rgb(123,213,85)',
PAUSED: 'rgb(250,122,122)',
REPEAT: '#3baeea',
REPEATING: '#3baeea',
DROPPED: 'rgb(232,93,117)'
}
</script>

View file

@ -15,10 +15,13 @@
missingFont: true,
maxConns: 20,
subtitleLanguage: 'eng',
audioLanguage: 'jpn'
audioLanguage: 'jpn',
enableDoH: false,
doHURL: 'https://cloudflare-dns.com/dns-query'
}
localStorage.removeItem('relations') // TODO: remove
export const set = { ...defaults, ...(JSON.parse(localStorage.getItem('settings')) || {}) }
if (set.enableDoH) window.IPC.emit('doh', set.doHURL)
if (!set.rssFeeds) { // TODO: remove ;-;
if (set.rssFeed) {
set.rssFeeds = [['New Releases', set.rssFeed]]
@ -363,6 +366,24 @@
<input type='checkbox' id='rss-autoplay' bind:checked={settings.rssAutoplay} />
<label for='rss-autoplay'>Auto-Play Torrents</label>
</div>
<div
class='custom-switch mb-10 pl-10 font-size-16 w-300'
data-toggle='tooltip'
data-placement='bottom'
data-title='Enables DNS Over HTTPS, useful if your ISP blocks certain domains'>
<input type='checkbox' id='rss-dohtoggle' bind:checked={settings.enableDoH} />
<label for='rss-dohtoggle'>Enable DoH</label>
</div>
<div
class='input-group input-group-lg form-control-lg mb-10 w-500'
data-toggle='tooltip'
data-placement='bottom'
data-title='Path To Folder Which To Use To Store Torrent Files'>
<div class='input-group-prepend'>
<span class='input-group-text w-150 justify-content-center'>DoH URL</span>
</div>
<input type='text' class='form-control' bind:value={settings.doHURL} placeholder={defaults.doHURL} />
</div>
</div>
</Tab>
<Tab>

View file

@ -1,7 +1,7 @@
<script>
export let peers
export let invite
export let cleanup
export let peers
export let invite
export let cleanup
</script>
<div class='d-flex flex-column py-20 root container card'>
@ -19,7 +19,7 @@ export let cleanup
{/if}
<h4 class='my-0 pl-20 mr-auto'>{peer.user?.name || 'Anonymous'}</h4>
{#if peer.user?.name}
<span class='material-icons pointer text-primary' on:click={() => window.IPC.emit('open', 'https://anilist.co/user/' + peer.user?.name)}> open_in_new </span>
<span class='material-icons pointer text-primary' on:pointerdown={() => window.IPC.emit('open', 'https://anilist.co/user/' + peer.user?.name)}> open_in_new </span>
{/if}
<!-- {#if state === 'host'}
<span class='material-icons ml-15 pointer text-danger' on:click={() => peer.peer.pc.close()}> logout </span>

View file

@ -1,168 +1,168 @@
<script context='module'>
import { writable } from 'svelte/store'
import { alID } from '@/modules/anilist.js'
import { add, client } from '@/modules/torrent.js'
import { generateRandomHexCode } from '@/modules/util.js'
import { addToast } from '@/lib/Toasts.svelte'
import { page } from '@/App.svelte'
import 'browser-event-target-emitter'
import { writable } from 'svelte/store'
import { alID } from '@/modules/anilist.js'
import { add, client } from '@/modules/torrent.js'
import { generateRandomHexCode } from '@/modules/util.js'
import { addToast } from '@/lib/Toasts.svelte'
import { page } from '@/App.svelte'
import 'browser-event-target-emitter'
import P2PCF from 'p2pcf'
import P2PCF from 'p2pcf'
export const w2gEmitter = new EventTarget()
export const w2gEmitter = new EventTarget()
const decode = TextDecoder.prototype.decode.bind(new TextDecoder('utf-8'))
const encode = TextEncoder.prototype.encode.bind(new TextEncoder())
const decode = TextDecoder.prototype.decode.bind(new TextDecoder('utf-8'))
const encode = TextEncoder.prototype.encode.bind(new TextEncoder())
const peers = writable({})
const peers = writable({})
export const state = writable(false)
export const state = writable(false)
let p2pcf = null
let p2pcf = null
function joinLobby (code = generateRandomHexCode(16)) {
if (p2pcf) cleanup()
p2pcf = new P2PCF(generateRandomHexCode(16), code)
p2pcf.on('peerconnect', async peer => {
console.log(peer.id)
console.log('connect')
const user = (await alID)?.data?.Viewer || {}
peer.send(
JSON.stringify({
type: 'init',
id: user.id || generateRandomHexCode(16),
user
})
)
})
p2pcf.on('peerclose', peer => {
peers.update(object => {
function joinLobby (code = generateRandomHexCode(16)) {
if (p2pcf) cleanup()
p2pcf = new P2PCF(generateRandomHexCode(16), code)
p2pcf.on('peerconnect', async peer => {
console.log(peer.id)
console.log('close', object[peer.id])
delete object[peer.id]
return object
})
})
p2pcf.on('msg', (peer, data) => {
data = typeof data === 'string' ? JSON.parse(data) : JSON.parse(decode(data))
console.log(data)
switch (data.type) {
case 'init':
console.log('init', data.user)
peers.update(object => {
object[peer.id] = {
peer,
user: data.user
}
return object
console.log('connect')
const user = (await alID)?.data?.Viewer || {}
peer.send(
JSON.stringify({
type: 'init',
id: user.id || generateRandomHexCode(16),
user
})
break
case 'player': {
if (setPlayerState(data)) w2gEmitter.emit('playerupdate', data)
break
}
case 'torrent': {
if (data.hash !== playerState.hash) {
playerState.hash = data.hash
add(data.magnet)
)
})
p2pcf.on('peerclose', peer => {
peers.update(object => {
console.log(peer.id)
console.log('close', object[peer.id])
delete object[peer.id]
return object
})
})
p2pcf.on('msg', (peer, data) => {
data = typeof data === 'string' ? JSON.parse(data) : JSON.parse(decode(data))
console.log(data)
switch (data.type) {
case 'init':
console.log('init', data.user)
peers.update(object => {
object[peer.id] = {
peer,
user: data.user
}
return object
})
break
case 'player': {
if (setPlayerState(data)) w2gEmitter.emit('playerupdate', data)
break
}
break
}
case 'index': {
if (playerState.index !== data.index) {
playerState.index = data.index
w2gEmitter.emit('setindex', data.index)
case 'torrent': {
if (data.hash !== playerState.hash) {
playerState.hash = data.hash
add(data.magnet)
}
break
}
case 'index': {
if (playerState.index !== data.index) {
playerState.index = data.index
w2gEmitter.emit('setindex', data.index)
}
break
}
default: {
console.error('Invalid message type', data)
}
break
}
default: {
console.error('Invalid message type', data)
}
})
p2pcf.start()
state.set(code)
console.log(p2pcf)
}
function setPlayerState (detail) {
let emit = false
for (const key of ['paused', 'time']) {
emit = emit || detail[key] !== playerState[key]
playerState[key] = detail[key]
}
return emit
}
w2gEmitter.on('player', ({ detail }) => {
if (setPlayerState(detail)) emit('player', detail)
})
w2gEmitter.on('index', ({ detail }) => {
if (playerState.index !== detail.index) {
emit('index', detail)
playerState.index = detail.index
}
})
p2pcf.start()
state.set(code)
console.log(p2pcf)
}
function setPlayerState (detail) {
let emit = false
for (const key of ['paused', 'time']) {
emit = emit || detail[key] !== playerState[key]
playerState[key] = detail[key]
client.on('magnet', ({ detail }) => {
if (detail.hash !== playerState.hash) {
playerState.hash = detail.hash
playerState.index = 0
emit('torrent', detail)
}
})
function emit (type, data) {
p2pcf?.broadcast(encode(JSON.stringify({ type, ...data })))
}
return emit
}
w2gEmitter.on('player', ({ detail }) => {
if (setPlayerState(detail)) emit('player', detail)
})
w2gEmitter.on('index', ({ detail }) => {
if (playerState.index !== detail.index) {
emit('index', detail)
playerState.index = detail.index
const playerState = {
paused: null,
time: null,
hash: null,
index: 0
}
})
client.on('magnet', ({ detail }) => {
if (detail.hash !== playerState.hash) {
playerState.hash = detail.hash
playerState.index = 0
emit('torrent', detail)
}
})
function emit (type, data) {
p2pcf?.broadcast(encode(JSON.stringify({ type, ...data })))
}
const playerState = {
paused: null,
time: null,
hash: null,
index: 0
}
function checkInvite (invite) {
if (invite) {
const match = invite.match(inviteRx)
if (match) {
page.set('watchtogether')
joinLobby(match[1])
function checkInvite (invite) {
if (invite) {
const match = invite.match(inviteRx)
if (match) {
page.set('watchtogether')
joinLobby(match[1])
}
}
}
}
const inviteRx = /([A-z0-9]{16})/i
window.IPC.on('w2glink', checkInvite)
const inviteRx = /([A-z0-9]{16})/i
window.IPC.on('w2glink', checkInvite)
function cleanup () {
state.set(false)
peers.set({})
p2pcf.destroy()
p2pcf = null
}
function invite () {
if (p2pcf) {
navigator.clipboard.writeText(`<miru://w2g/${p2pcf.roomId}>`)
addToast({
title: 'Copied to clipboard',
text: 'Copied invite URL to clipboard',
type: 'primary',
duration: '5000'
})
function cleanup () {
state.set(false)
peers.set({})
p2pcf.destroy()
p2pcf = null
}
function invite () {
if (p2pcf) {
navigator.clipboard.writeText(`https://miru.watch/w2g/${p2pcf.roomId}`)
addToast({
title: 'Copied to clipboard',
text: 'Copied invite URL to clipboard',
type: 'primary',
duration: '5000'
})
}
}
}
</script>
<script>
import Lobby from './Lobby.svelte'
import Lobby from './Lobby.svelte'
let joinText
let joinText
$: checkInvite(joinText)
$: checkInvite(joinText)
</script>
<div class='d-flex h-full align-items-center flex-column content'>

View file

@ -1,32 +0,0 @@
const P2PT = require('p2pt')
class P2PWorker extends P2PT {
constructor (...args) {
super(...args)
onmessage = this.handleMessage.bind(this)
this.start()
}
dispatch (type, data) {
postMessage({ type, data })
}
handleMessage ({ data }) {
switch (data.type) {
case 'current': {
break
}
case 'torrent': {
break
}
}
}
}
let client = null
onmessage = ({ data }) => {
if (!client && data.type === 'settings') client = new P2PWorker(data.data)
if (data.type === 'destroy') client?.predestroy()
}