2023-10-30 09:36:16 +01:00
|
|
|
import { spawn } from 'node:child_process'
|
|
|
|
import appStore from '@electron/helpers/store.js'
|
|
|
|
import {
|
|
|
|
adbPath,
|
|
|
|
gnirehtetApkPath,
|
|
|
|
gnirehtetPath,
|
|
|
|
} from '@electron/configs/index.js'
|
|
|
|
|
|
|
|
const appDebug = appStore.get('common.debug') || false
|
|
|
|
|
|
|
|
let adbkit = null
|
|
|
|
|
|
|
|
const shell = async (command, { debug = false, stdout, stderr } = {}) => {
|
2023-10-30 09:44:24 +01:00
|
|
|
const spawnPath = appStore.get('common.gnirehtetPath') || gnirehtetPath
|
2023-10-30 09:36:16 +01:00
|
|
|
const ADB = appStore.get('common.adbPath') || adbPath
|
|
|
|
|
2023-10-30 10:26:13 +01:00
|
|
|
if (!spawnPath) {
|
|
|
|
throw new Error(
|
|
|
|
'Failed to retrieve Gnirehtet dependency path. If you\'re using macOS, please ensure that the dependency is installed correctly.',
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-10-30 09:36:16 +01:00
|
|
|
const GNIREHTET_APK = gnirehtetApkPath
|
|
|
|
|
|
|
|
const args = command.split(' ')
|
|
|
|
|
|
|
|
console.log('gnirehtet.shell.spawnPath', spawnPath)
|
|
|
|
console.log('gnirehtet.shell.adbPath', adbPath)
|
2023-10-31 09:37:17 +01:00
|
|
|
console.log('gnirehtet.shell.command', command)
|
2023-10-30 09:36:16 +01:00
|
|
|
|
|
|
|
const gnirehtetProcess = spawn(`"${spawnPath}"`, args, {
|
|
|
|
env: { ...process.env, ADB, GNIREHTET_APK },
|
|
|
|
shell: true,
|
|
|
|
encoding: 'utf8',
|
|
|
|
})
|
|
|
|
|
|
|
|
gnirehtetProcess.stdout.on('data', (data) => {
|
|
|
|
const stringData = data.toString()
|
|
|
|
|
|
|
|
if (debug) {
|
2023-10-31 09:37:17 +01:00
|
|
|
console.log(`${command}.gnirehtet.process.stdout.data:`, stringData)
|
2023-10-30 09:36:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (stdout) {
|
|
|
|
stdout(stringData, gnirehtetProcess)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2023-11-14 03:53:58 +01:00
|
|
|
let lastStderr = ''
|
2023-10-30 09:36:16 +01:00
|
|
|
gnirehtetProcess.stderr.on('data', (data) => {
|
|
|
|
const stringData = data.toString()
|
|
|
|
|
2023-11-14 03:53:58 +01:00
|
|
|
lastStderr = stringData
|
|
|
|
|
2023-10-30 09:36:16 +01:00
|
|
|
if (debug) {
|
2023-10-31 09:37:17 +01:00
|
|
|
console.error(`${command}.gnirehtet.process.stderr.data:`, stringData)
|
2023-10-30 09:36:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (stderr) {
|
|
|
|
stderr(stringData, gnirehtetProcess)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
gnirehtetProcess.on('close', (code) => {
|
2023-10-31 09:37:17 +01:00
|
|
|
console.log(`${command}.gnirehtet.process.close.code`, code)
|
|
|
|
|
2023-10-30 09:36:16 +01:00
|
|
|
if (code === 0) {
|
|
|
|
resolve()
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
reject(new Error(`Command failed with code ${code}`))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
gnirehtetProcess.on('error', (err) => {
|
|
|
|
reject(err)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-10-31 09:37:17 +01:00
|
|
|
const install = deviceId => shell(`install "${deviceId}"`)
|
2023-11-14 03:56:00 +01:00
|
|
|
|
2023-10-31 09:37:17 +01:00
|
|
|
const start = deviceId => shell(`start "${deviceId}"`)
|
2023-11-14 03:56:00 +01:00
|
|
|
|
2023-10-31 09:37:17 +01:00
|
|
|
const stop = deviceId => shell(`stop "${deviceId}"`)
|
2023-11-14 03:56:00 +01:00
|
|
|
|
2023-10-31 09:37:17 +01:00
|
|
|
const tunnel = deviceId => shell(`tunnel "${deviceId}"`)
|
2023-10-31 16:19:34 +01:00
|
|
|
|
|
|
|
const installed = async (deviceId) => {
|
|
|
|
const res = await adbkit.isInstalled(deviceId, 'com.genymobile.gnirehtet')
|
|
|
|
console.log('gnirehtet.apk.installed', res)
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2023-10-30 09:36:16 +01:00
|
|
|
let relayProcess = null
|
2023-10-31 16:19:34 +01:00
|
|
|
const stopRelayProcess = () => {
|
|
|
|
if (!relayProcess) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
relayProcess?.kill()
|
|
|
|
relayProcess = null
|
|
|
|
}
|
2023-10-31 09:37:17 +01:00
|
|
|
|
2023-10-30 09:36:16 +01:00
|
|
|
const relay = async (args) => {
|
2023-10-31 09:37:17 +01:00
|
|
|
stopRelayProcess()
|
2023-10-30 09:36:16 +01:00
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
shell('relay', {
|
|
|
|
...args,
|
|
|
|
debug: appDebug,
|
|
|
|
stdout: (_, process) => {
|
|
|
|
if (!relayProcess) {
|
|
|
|
relayProcess = process
|
|
|
|
}
|
|
|
|
resolve(process)
|
|
|
|
},
|
2023-10-31 16:19:34 +01:00
|
|
|
stderr: (error) => {
|
|
|
|
reject(error)
|
|
|
|
},
|
2023-10-31 09:37:17 +01:00
|
|
|
}).catch((error) => {
|
2023-10-30 09:36:16 +01:00
|
|
|
reject(error)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
const run = async (deviceId) => {
|
2023-10-31 16:19:34 +01:00
|
|
|
await relay().catch((error) => {
|
|
|
|
throw new Error(error?.message || 'Gnirehtet Relay fail')
|
2023-10-30 09:36:16 +01:00
|
|
|
})
|
2023-10-30 10:26:13 +01:00
|
|
|
|
2023-11-03 07:07:27 +01:00
|
|
|
const gnirehtetFix = appStore.get('common.gnirehtetFix') || false
|
|
|
|
const isInstalled = installed(deviceId)
|
|
|
|
|
|
|
|
if (gnirehtetFix || !isInstalled) {
|
|
|
|
console.log('Installing Gnirehtet Client...')
|
|
|
|
await install(deviceId).catch((error) => {
|
|
|
|
throw new Error(error?.message || 'Gnirehtet Install Client fail')
|
|
|
|
})
|
|
|
|
}
|
2023-10-30 10:26:13 +01:00
|
|
|
|
2023-10-31 16:19:34 +01:00
|
|
|
await start(deviceId).catch((error) => {
|
|
|
|
throw new Error(error?.message || 'Gnirehtet Start fail')
|
2023-10-30 09:36:16 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
window.addEventListener('beforeunload', () => {
|
|
|
|
stop()
|
|
|
|
|
2023-10-31 16:19:34 +01:00
|
|
|
stopRelayProcess()
|
2023-10-30 09:36:16 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
export default (options = {}) => {
|
|
|
|
adbkit = options.adbkit
|
|
|
|
|
|
|
|
return {
|
|
|
|
shell,
|
|
|
|
relay,
|
|
|
|
install,
|
|
|
|
installed,
|
|
|
|
start,
|
|
|
|
stop,
|
|
|
|
tunnel,
|
|
|
|
run,
|
|
|
|
}
|
|
|
|
}
|