builtin YACE launcher added

master
Henry Jameson 1 year ago
parent 396d60fca2
commit 6f99d6c8b0
  1. 41
      index.js
  2. 2
      package.json
  3. BIN
      sm.png
  4. 10
      statemachine.js
  5. 36
      yacardemu.js
  6. 93
      yarn.lock

@ -17,8 +17,10 @@ import { ICCard } from './nfc.js'
program program
.option('-i, --i2c-bus <num>', 'i2c bus to use for LCD display') .option('-i, --i2c-bus <num>', 'i2c bus to use for LCD display')
.option('--noLCD', 'don\'t use LCD display, not recommended for production use') .option('--noLCD', 'don\'t use LCD display, not recommended for production use')
.option('-e, --emulator-port <num>', 'port of the card emulator') .option('-e, --emulator-port <num>', 'port of the card emulator, for builtin YACE default is 8999')
.option('-c, --cards-location <path>', 'path where card data will be saved') .option('-c, --cards-location <path>', 'path where card data will be saved')
.option('-d, --serial-device <path>', 'path to serial device used')
.option('-r, --remote-yace', 'Don\'t start YACardEmu automatically')
program.parse(); program.parse();
@ -37,21 +39,26 @@ if (opts.noLCD) {
process.exit(1) process.exit(1)
} }
if (!(opts.emulatorPort > 0)) { if (!(opts.emulatorPort > 0) && opts.remoteYace) {
logger.error('Emulator port not configured!') logger.error('Emulator port not configured!')
process.exit(1) process.exit(1)
} }
if (!(opts.serialDevice.length > 0) && !opts.remoteYace) {
logger.error('Serial device not configured!')
process.exit(1)
}
if (!(opts.cardsLocation.length > 0)) { if (!(opts.cardsLocation.length > 0)) {
logger.error('Saves location not set!') logger.error('Saves location not set!')
process.exit(1) process.exit(1)
} }
const port = opts.emulatorPort const port = opts.emulatorPort || 8999
logger.info('Starting up') logger.info('Starting up')
const sm = wmmt3() const sm = wmmt3.statemachine()
const status = { const status = {
card: null, card: null,
countdown: 0, countdown: 0,
@ -77,11 +84,27 @@ const countDown = (secs, callback) => {
} }
logger.info('Starting YACE api') logger.info('Starting YACE api')
const yace = YACE(port) const yace = YACE(port, saves, opts.serialDevice, wmmt3)
yace.once('error', () => setTimeout(() => { if (opts.remoteYace) {
yace.startPolling() yace.on('error', () => {
logger.error('Emulator unavailable, retrying in 1 sec') logger.error('Emulator unavailable, retrying in 1 sec')
}, 1000)) setTimeout(() => {
yace.startPolling()
}, 1000)
})
} else {
yace.on('error', () => {
logger.error('Emulator error!')
setTimeout(() => {
yace.startPolling()
}, 1000)
})
yace.on('exit', () => {
logger.error('Emulator exited!')
process.exit(1)
})
yace.initTmp()
}
yace.startPolling() yace.startPolling()
const onInit = () => { const onInit = () => {

@ -7,6 +7,8 @@
"nfc-pcsc": "^0.8.1", "nfc-pcsc": "^0.8.1",
"node-fetch": "^3.2.9", "node-fetch": "^3.2.9",
"raspberrypi-liquid-crystal": "^1.18.0", "raspberrypi-liquid-crystal": "^1.18.0",
"tmp": "^0.2.1",
"tmp-promise": "^3.0.3",
"yarn": "^1.22.18" "yarn": "^1.22.18"
} }
} }

BIN
sm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

@ -4,7 +4,7 @@ import chalk from 'chalk'
import StateMachine from 'javascript-state-machine' import StateMachine from 'javascript-state-machine'
//import visualize from 'javascript-state-machine/lib/visualize.js' //import visualize from 'javascript-state-machine/lib/visualize.js'
export const wmmt3 = () => { const wmmt3sm = () => {
const logger = Logger(chalk.red('[WMMT3]')) const logger = Logger(chalk.red('[WMMT3]'))
return new StateMachine({ return new StateMachine({
init: 'idle', init: 'idle',
@ -45,5 +45,11 @@ export const wmmt3 = () => {
} }
}) })
} }
//console.log(visualize(WMMT3CardSM)) //console.log(visualize(WMMT3CardSM))
export const wmmt3 = {
game: 'Wangan Midnight Maximum Tune 3(DX(+))',
baud: 38400,
parity: 'even',
statemachine: wmmt3sm
}

@ -1,10 +1,13 @@
import fetch from 'node-fetch' import fetch from 'node-fetch'
import chalk from 'chalk' import chalk from 'chalk'
import EventEmitter from 'events' import EventEmitter from 'events'
import tmp from 'tmp-promise'
import { writeFile } from 'node:fs/promises';
import { Logger } from './statuslogger.js' import { Logger } from './statuslogger.js'
import { spawn } from 'node:child_process';
export const YACE = (port) => { export const YACE = (port, saves, device, game) => {
const logger = Logger(chalk.yellow('[YACE]')) const logger = Logger(chalk.yellow('[YACE]'))
const emitter = new EventEmitter() const emitter = new EventEmitter()
@ -91,5 +94,36 @@ export const YACE = (port) => {
return fetch(`http://127.0.0.1:${port}/api/v1/insertedCard?cardname=` + id, { method: 'POST' }) return fetch(`http://127.0.0.1:${port}/api/v1/insertedCard?cardname=` + id, { method: 'POST' })
} }
const yaceIniTemplate = (path, port, device, { baud, parity }) => `
[config]
basepath = ${path}
serialpath = ${device}
serialbaud = ${baud}
serialparity = ${parity}
apiport = ${port}
autoselectedcard = dummy.bin
`
emitter.initTmp = () => {
tmp.setGracefulCleanup();
let dir = null
let cleanupFunc = null
tmp.dir().then(({ path, cleanup }) => {
dir = path,
cleanupFunc = cleanup
return writeFile(path + '/config.ini', yaceIniTemplate(saves, port, device, game))
}).then(() => {
const yace = spawn('YACardEmu', [], { cwd: dir })
yace.stdout.on('data', data => data.toString().split(/\n/g).filter(x => x).forEach(d => logger.debug(d)))
yace.on('exit', data => {
logger.error('YACE Exited!')
emitter.emit('exit')
})
})
}
return emitter return emitter
} }

@ -10,6 +10,11 @@
bindings "^1.5.0" bindings "^1.5.0"
nan "^2.14.0" nan "^2.14.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
bindings@^1.5.0: bindings@^1.5.0:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
@ -17,6 +22,14 @@ bindings@^1.5.0:
dependencies: dependencies:
file-uri-to-path "1.0.0" file-uri-to-path "1.0.0"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
chalk@^5.0.1: chalk@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6"
@ -27,6 +40,11 @@ commander@^9.4.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd"
integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
data-uri-to-buffer@^4.0.0: data-uri-to-buffer@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b"
@ -52,6 +70,23 @@ formdata-polyfill@^4.0.10:
dependencies: dependencies:
fetch-blob "^3.1.2" fetch-blob "^3.1.2"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
i2c-bus@^5.1.0: i2c-bus@^5.1.0:
version "5.2.2" version "5.2.2"
resolved "https://registry.yarnpkg.com/i2c-bus/-/i2c-bus-5.2.2.tgz#0c727f5e99443c5734b4f0e05b45748ba85008fa" resolved "https://registry.yarnpkg.com/i2c-bus/-/i2c-bus-5.2.2.tgz#0c727f5e99443c5734b4f0e05b45748ba85008fa"
@ -60,11 +95,31 @@ i2c-bus@^5.1.0:
bindings "^1.5.0" bindings "^1.5.0"
nan "^2.14.2" nan "^2.14.2"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
javascript-state-machine@^3.1.0: javascript-state-machine@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/javascript-state-machine/-/javascript-state-machine-3.1.0.tgz#06eeb2136a6a19ae1b56105c25caec283dd5cd14" resolved "https://registry.yarnpkg.com/javascript-state-machine/-/javascript-state-machine-3.1.0.tgz#06eeb2136a6a19ae1b56105c25caec283dd5cd14"
integrity sha512-BwhYxQ1OPenBPXC735RgfB+ZUG8H3kjsx8hrYTgWnoy6TPipEy4fiicyhT2lxRKAXq9pG7CfFT8a2HLr6Hmwxg== integrity sha512-BwhYxQ1OPenBPXC735RgfB+ZUG8H3kjsx8hrYTgWnoy6TPipEy4fiicyhT2lxRKAXq9pG7CfFT8a2HLr6Hmwxg==
minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
nan@^2.14.0, nan@^2.14.1, nan@^2.14.2: nan@^2.14.0, nan@^2.14.1, nan@^2.14.2:
version "2.16.0" version "2.16.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916"
@ -91,6 +146,18 @@ node-fetch@^3.2.9:
fetch-blob "^3.1.4" fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10" formdata-polyfill "^4.0.10"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
raspberrypi-liquid-crystal@^1.18.0: raspberrypi-liquid-crystal@^1.18.0:
version "1.18.0" version "1.18.0"
resolved "https://registry.yarnpkg.com/raspberrypi-liquid-crystal/-/raspberrypi-liquid-crystal-1.18.0.tgz#95a6316502515881ae102226bae0dcab33b722de" resolved "https://registry.yarnpkg.com/raspberrypi-liquid-crystal/-/raspberrypi-liquid-crystal-1.18.0.tgz#95a6316502515881ae102226bae0dcab33b722de"
@ -99,6 +166,13 @@ raspberrypi-liquid-crystal@^1.18.0:
i2c-bus "^5.1.0" i2c-bus "^5.1.0"
sleep "^6.3.0" sleep "^6.3.0"
rimraf@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
sleep@^6.3.0: sleep@^6.3.0:
version "6.3.0" version "6.3.0"
resolved "https://registry.yarnpkg.com/sleep/-/sleep-6.3.0.tgz#c524e0e6d8d2e45d3f14e0ba5650fbe45f2ae876" resolved "https://registry.yarnpkg.com/sleep/-/sleep-6.3.0.tgz#c524e0e6d8d2e45d3f14e0ba5650fbe45f2ae876"
@ -106,11 +180,30 @@ sleep@^6.3.0:
dependencies: dependencies:
nan "^2.14.1" nan "^2.14.1"
tmp-promise@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7"
integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==
dependencies:
tmp "^0.2.0"
tmp@^0.2.0, tmp@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==
dependencies:
rimraf "^3.0.0"
web-streams-polyfill@^3.0.3: web-streams-polyfill@^3.0.3:
version "3.2.1" version "3.2.1"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
yarn@^1.22.18: yarn@^1.22.18:
version "1.22.18" version "1.22.18"
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.18.tgz#05b822ade8c672987bab8858635145da0850f78a" resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.18.tgz#05b822ade8c672987bab8858635145da0850f78a"

Loading…
Cancel
Save