pcsx-redux/tools/vscode-extension/pcsx-redux.js
Nicolas "Pixel" Noble f2a316c884 Formatting.
2023-12-30 12:34:33 -08:00

210 lines
5.8 KiB
JavaScript

'use strict'
const vscode = require('vscode')
const Axios = require('axios').Axios
const axios = new Axios({})
const { mkdirp, copy } = require('fs-extra')
const jsonStream = require('JSONStream')
const path = require('path')
const downloader = require('./downloader.js')
const util = require('node:util')
const fs = require('fs-extra')
const dmg = require('dmg')
const dmgMount = util.promisify(dmg.mount)
const dmgUnmount = util.promisify(dmg.unmount)
const terminal = require('./terminal.js')
const execAsync = require('node:child_process').exec
const exec = util.promisify(execAsync)
const os = require('node:os')
const updateInfo = {
win32: {
updateCatalog:
'https://install.appcenter.ms/api/v0.1/apps/grumpycoders/pcsx-redux-win64-cli/distribution_groups/public/public_releases',
updateInfoBase:
'https://install.appcenter.ms/api/v0.1/apps/grumpycoders/pcsx-redux-win64-cli/distribution_groups/public/releases/',
method: 'appcenter',
fileType: 'zip'
},
linux: {
updateCatalog:
'https://install.appcenter.ms/api/v0.1/apps/grumpycoders/pcsx-redux-linux64/distribution_groups/public/public_releases',
updateInfoBase:
'https://install.appcenter.ms/api/v0.1/apps/grumpycoders/pcsx-redux-linux64/distribution_groups/public/releases/',
method: 'appcenter',
fileType: 'zip'
},
darwin: {
updateCatalog:
'https://install.appcenter.ms/api/v0.1/apps/grumpycoders/pcsx-redux-macos/distribution_groups/public/public_releases',
updateInfoBase:
'https://install.appcenter.ms/api/v0.1/apps/grumpycoders/pcsx-redux-macos/distribution_groups/public/releases/',
method: 'appcenter',
fileType: 'dmg'
}
}
let globalStorageUri
function isSupported () {
let supported = false
if (process.arch === 'x64') supported = true
if (process.platform === 'darwin' && process.arch === 'arm64') {
supported = true
}
return supported
}
function binaryPath () {
switch (process.platform) {
case 'win32':
return vscode.Uri.joinPath(
globalStorageUri,
'pcsx-redux',
'pcsx-redux.exe'
).fsPath
case 'linux':
return vscode.Uri.joinPath(
globalStorageUri,
'PCSX-Redux-HEAD-x86_64.AppImage'
).fsPath
case 'darwin':
return vscode.Uri.joinPath(
globalStorageUri,
'PCSX-Redux.app',
'Contents',
'MacOS',
'PCSX-Redux'
).fsPath
}
}
function checkLocalFile (filename) {
return new Promise((resolve) => {
fs.access(filename, fs.constants.F_OK, (err) => {
resolve(!err)
})
})
}
exports.check = () => {
const path = binaryPath()
if (path === undefined) return Promise.resolve(false)
return checkLocalFile(path)
}
exports.install = async () => {
if (!isSupported()) {
throw new Error(
'Unsupported platform. You can still use PCSX-Redux by compiling it from source.'
)
}
if (process.platform === 'win32') {
const dllPath = 'C:\\Windows\\System32\\msvcp140_atomic_wait.dll'
if (!(await checkLocalFile(dllPath))) {
const fullPath = path.join(os.tmpdir(), 'vc_redist.x64.exe')
await downloader.downloadFile(
'https://aka.ms/vs/17/release/vc_redist.x64.exe',
fullPath
)
await exec(fullPath)
}
}
const updateInfoForPlatform = updateInfo[process.platform]
const outputDir =
process.platform === 'win32'
? vscode.Uri.joinPath(globalStorageUri, 'pcsx-redux').fsPath
: globalStorageUri.fsPath
await mkdirp(outputDir)
const responseCatalog = await axios.request({
method: 'get',
url: updateInfoForPlatform.updateCatalog,
responseType: 'stream'
})
const updateId = await new Promise((resolve, reject) => {
let highestId = -1
responseCatalog.data
.on('close', () => resolve(highestId))
.on('error', (err) => reject(err))
.pipe(jsonStream.parse([true]))
.on('data', (data) => {
if (data.id > highestId) highestId = data.id
})
})
const response = await axios.request({
method: 'get',
url: updateInfoForPlatform.updateInfoBase + updateId,
responseType: 'stream'
})
const downloadUrl = await new Promise((resolve, reject) => {
let downloadUrl
response.data
.on('close', () => resolve(downloadUrl))
.on('error', (err) => reject(err))
.pipe(jsonStream.parse(['download_url']))
.on('data', (data) => {
downloadUrl = data
})
})
if (downloadUrl === undefined) {
throw new Error('Invalid AppCenter catalog information.')
}
await downloader.downloadFile(
downloadUrl,
process.platform === 'darwin' ? path.join(outputDir, 'PCSX-Redux.dmg') : outputDir,
updateInfoForPlatform.fileType === 'zip'
)
switch (process.platform) {
case 'linux':
return fs.chmod(
path.join(outputDir, 'PCSX-Redux-HEAD-x86_64.AppImage'),
0o775
)
case 'darwin':
const mountPoint = await dmgMount(path.join(outputDir, 'PCSX-Redux.dmg'))
await copy(
path.join(mountPoint, 'PCSX-Redux.app'),
path.join(outputDir, 'PCSX-Redux.app'),
{ overwrite: true }
)
return dmgUnmount(mountPoint)
}
}
exports.launch = async () => {
let path = binaryPath()
if (path === undefined || !(await checkLocalFile(path))) path = 'PCSX-Redux'
const cwd = vscode.Uri.joinPath(
globalStorageUri,
'pcsx-redux-settings'
).fsPath
await fs.mkdirp(cwd)
const pcdrvOpts = []
if (vscode.workspace.workspaceFolders) {
pcdrvOpts.push('-pcdrv')
pcdrvOpts.push('-pcdrvbase')
pcdrvOpts.push(vscode.workspace.workspaceFolders[0].uri.fsPath)
}
return terminal.run(
path,
[
'-stdout',
'-lua_stdout',
'-interpreter',
'-debugger',
'-gdb',
'-portable',
'-noupdate',
...pcdrvOpts
],
{ name: 'PCSX-Redux', cwd }
)
}
exports.setGlobalStorageUri = (uri) => {
globalStorageUri = uri
}