Skip to content

Commit

Permalink
reset_blocked_ips, start_resetting_blocked_ips;
Browse files Browse the repository at this point in the history
refactor state transition to prevent multiple time loop;
  • Loading branch information
ShenHongFei committed Aug 14, 2021
1 parent 9ec537b commit 871c4fe
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 60 deletions.
138 changes: 108 additions & 30 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isIPv6, isIPv4 } from 'net'

import { request_page, request_json, fread_lines, fwrite, delay, log_line, inspect, start } from 'xshell'
import { request_page, request_json, fwrite, delay, log_line, inspect, start, log_section, fread } from 'xshell'
import QQWRY from 'lib-qqwry'

export * from './resume-data'
Expand Down Expand Up @@ -430,14 +430,24 @@ export class Torrent {

export class UTorrent {
root_url: string

username: string
password: string
ipfilter_dat: string

fp_ipfilter: string

/** 启动时 ipfilter 中已有的数据 */
static_ipfilter: string

/** 检测 peers 并屏蔽的时间间隔 */
interval: number

state: 'IDLE' | 'RUNNING' = 'IDLE'
/** 间隔 interval 秒自动重置当前时间间隔内被动态屏蔽的 IP */
interval_reset: number

state: 'INIT' | 'IDLE' | 'RUNNING' = 'INIT'

state_resetting: 'INIT' | 'IDLE' | 'RUNNING' = 'INIT'

print: {
/** ['下载'] */
Expand All @@ -453,9 +463,9 @@ export class UTorrent {

token: string

torrents: Torrent[]
blocked_ips = new Set<string>()

blocked_ips: Set<string>
torrents: Torrent[]


static async launch (exe: string) {
Expand All @@ -474,8 +484,9 @@ export class UTorrent {
root_url: string
username: string
password: string
ipfilter_dat: string
fp_ipfilter: string
interval: number
interval_reset: number

/** print?: true */
print?: boolean | {
Expand All @@ -487,12 +498,10 @@ export class UTorrent {
}
}
) {

let utorrent = new UTorrent({
...options,
blocked_ips: new Set((
await fread_lines(options.ipfilter_dat)
).trim_lines()),
...options,
static_ipfilter: await fread(options.fp_ipfilter),
blocked_ips: new Set(),
print: (() => {
if (!('print' in options)) return { torrents: true, peers: true }
if (typeof options.print === 'boolean') return { torrents: options.print, peers: options.print }
Expand All @@ -509,7 +518,7 @@ export class UTorrent {

/** get token */
async get_token () {
const $ = await request_page(this.root_url + 'token.html', {
const $ = await request_page(`${this.root_url}token.html`, {
auth: {
username: this.username,
password: this.password
Expand Down Expand Up @@ -612,7 +621,14 @@ export class UTorrent {
this.blocked_ips.add(peer.ip)
})

await fwrite(this.ipfilter_dat, [...this.blocked_ips].join_lines() + '\n', { print: Boolean(this.print.peers || this.print.torrents) })
await fwrite(
this.fp_ipfilter,
(
this.static_ipfilter + '\n' +
[...this.blocked_ips].join_lines() + '\n'
),
{ print: Boolean(this.print.peers || this.print.torrents) }
)

await this.reload_ipfilter()

Expand All @@ -633,10 +649,17 @@ export class UTorrent {

async reset_ipfilter () {
this.blocked_ips = new Set()
await fwrite(this.ipfilter_dat, '')
await fwrite(this.fp_ipfilter, '')
await this.reload_ipfilter()
}

async reset_blocked_ips () {
await fwrite(this.fp_ipfilter, this.static_ipfilter)
log_section('reset dynamic blocked ips', { time: true })
this.blocked_ips = new Set()
await utorrent.reload_ipfilter()
}


find_torrent (name_pattern: string | RegExp) {
if (typeof name_pattern === 'string')
Expand All @@ -647,31 +670,86 @@ export class UTorrent {

async start_blocking () {
await this.get_token()

if (this.state === 'RUNNING') return

if (this.state === 'IDLE') {
this.state = 'RUNNING'
return
}

// this.state === 'INIT'

this.state = 'RUNNING'
while (this.state === 'RUNNING') {
if (this.print.torrents || this.print.peers)
console.log('\n\n\n' + new Date().to_str())

try {
if (this.print.torrents) {
await this.print_torrents()
log_line(200)
await this.block_peers(this.torrents)
} else
await this.block_peers()

// start blocking
;(async () => {
while (this.state === 'RUNNING') {
if (this.print.torrents || this.print.peers)
console.log('\n\n\n' + new Date().to_str())

try {
if (this.print.torrents) {
await this.print_torrents()
log_line(200)
await this.block_peers(this.torrents)
} else
await this.block_peers()
} catch (error) {
this.state = 'INIT'
throw error
}

await delay(this.interval)
} catch (error) {
this.state = 'IDLE'
throw error
}

if (this.state === 'IDLE')
this.state = 'INIT'
})()

await this.start_resetting_blocked_ips()
}


async start_resetting_blocked_ips () {
if (this.state_resetting === 'RUNNING') return

if (this.state_resetting === 'IDLE') {
this.state_resetting = 'RUNNING'
return
}
console.log('uTorrent blocking stopped')

// this.state_resetting === 'INIT'

this.state_resetting = 'RUNNING'
;(async () => {
while (true) {
await delay(this.interval_reset)
if (this.state_resetting !== 'RUNNING') break
await this.reset_blocked_ips()
}

if (this.state_resetting === 'IDLE')
this.state_resetting = 'INIT'
})()
}


stop_blocking () {
async stop_blocking () {
if (this.state === 'INIT') {
console.log('blocking hasn\'t started')
return
}

if (this.state === 'IDLE') {
console.log('blocking already stopped')
return
}

// this.state === 'RUNNING'
this.state = 'IDLE'
await this.reset_blocked_ips()
console.log('uTorrent stopped blocking')
}


Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "utorrent-block-xunlei",
"version": "0.0.5",
"version": "0.0.6",
"main": "./index.js",
"bin": {
"utorrent-block-xunlei": "./utorrent-block-xunlei.js"
Expand Down
41 changes: 14 additions & 27 deletions utorrent-block-xunlei.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,52 +38,39 @@ declare global {

program.parse(process.argv)

const { hostname, port, username, password, ipfilter: ipfilter_dat, interval, intervalReset: interval_reset } = program.opts()
const opts = program.opts()

const { hostname, username, password }: { hostname: string, username: string, password: string } = opts as any
const port = Number(opts.port)
const fp_ipfilter = (opts.ipfilter as string).to_slash()
const interval = Number(opts.interval) * 1000
const interval_reset = Number(opts.intervalReset) * 1000


const options = {
root_url: `http://${hostname}:${port}/gui/`,
username,
password,
ipfilter_dat,
interval: Number(interval) * 1000,
interval_reset: Number(interval_reset) * 1000,
fp_ipfilter,
interval,
interval_reset,
}

console.log(options)

let ipfilter_bak: string
if (options.interval_reset)
ipfilter_bak = await fread(options.ipfilter_dat)

let utorrent = await UTorrent.connect(options)

global.utorrent = utorrent

log_section('started blocking', { time: true, color: 'green' })

utorrent.start_blocking()
await utorrent.start_blocking()


async function reset_dynamic_blocked_ips () {
await fwrite(options.ipfilter_dat, ipfilter_bak)
log_section('reset dynamic blocked ips', { time: true })
utorrent.blocked_ips = new Set()
await utorrent.reload_ipfilter()
}
log_section('started blocking', { time: true, color: 'green' })

async function exit () {
utorrent.stop_blocking()
await reset_dynamic_blocked_ips()
await utorrent.stop_blocking()
process.exit()
}

;(async () => {
while (true) {
await delay(options.interval_reset)
await reset_dynamic_blocked_ips()
}
})()

global.exit = exit

repl.start({
Expand Down

0 comments on commit 871c4fe

Please sign in to comment.