Skip to content

Commit

Permalink
Merge pull request #51 from project-yuki/b0.12
Browse files Browse the repository at this point in the history
B0.12
  • Loading branch information
tinyAdapter authored Dec 7, 2019
2 parents 429cb07 + 3ddcdbe commit a317c6f
Show file tree
Hide file tree
Showing 22 changed files with 526 additions and 151 deletions.
5 changes: 4 additions & 1 deletion src/common/IpcTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum IpcTypes {
REQUEST_REMOVE_GAME = 'request-remove-game',
HAS_REMOVED_GAME = 'has-removed-game',
REQUEST_RUN_GAME = 'request-run-game',
HAS_RUNNING_GAME = 'has-running-game',
REQUEST_TRANSLATION = 'request-translation',
HAS_TRANSLATION = 'has-translation',
APP_EXIT = 'app-exit',
Expand All @@ -31,7 +32,9 @@ enum IpcTypes {
HAS_NEW_DEBUG_MESSAGE = 'has-new-debug-message',
GAME_ABORTED = 'game-aborted',
REQUEST_DICT = 'request-dict',
HAS_DICT = 'has-dict'
HAS_DICT = 'has-dict',
REQUEST_PROCESSES = 'request-processes',
HAS_PROCESSES = 'has-processes'
}

export default IpcTypes
37 changes: 37 additions & 0 deletions src/main/BaseGame.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const debug = require('debug')('yuki:game')
import { EventEmitter } from 'events'
import Hooker from './Hooker'
import { registerProcessExitCallback } from './Win32'

export default abstract class BaseGame extends EventEmitter {
protected pids: number[]

constructor () {
super()
this.pids = []
}

public abstract start (): void

public getPids () {
return this.pids
}

public abstract getInfo (): yuki.Game

protected afterGetPids () {
this.injectProcessByPid()
this.registerProcessExitCallback()
this.emit('started', this)
}

private injectProcessByPid () {
this.pids.map((pid) => Hooker.getInstance().injectProcess(pid))
}

private registerProcessExitCallback () {
registerProcessExitCallback(this.pids, () => {
this.emit('exited', this)
})
}
}
27 changes: 4 additions & 23 deletions src/main/Game.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { exec } from 'child_process'
const debug = require('debug')('yuki:game')
import { EventEmitter } from 'events'
import BaseGame from './BaseGame'
import ConfigManager from './config/ConfigManager'
import Hooker from './Hooker'
import { registerProcessExitCallback } from './Win32'

export default class Game extends EventEmitter {
export default class Game extends BaseGame {
private static readonly TIMEOUT = 1000
private static readonly MAX_RESET_TIME = 10
private execString: string
private path: string
private code: string
private pids: number[]
private name: string
private localeChanger: string
private exeName: string
Expand All @@ -27,15 +24,11 @@ export default class Game extends EventEmitter {
this.exeName = ''
}

public async start () {
public start () {
this.execGameProcess()
this.registerHookerWithPid()
}

public getPids () {
return this.pids
}

public getInfo (): yuki.Game {
return {
name: this.name,
Expand Down Expand Up @@ -83,9 +76,7 @@ export default class Game extends EventEmitter {
this.emit('exited')
return
}
this.injectProcessByPid()
this.emit('started', this)
this.registerProcessExitCallback()
this.afterGetPids()
}

private findPids () {
Expand Down Expand Up @@ -133,14 +124,4 @@ export default class Game extends EventEmitter {
}
return pids
}

private injectProcessByPid () {
this.pids.map((pid) => Hooker.getInstance().injectProcess(pid))
}

private registerProcessExitCallback () {
registerProcessExitCallback(this.pids, () => {
this.emit('exited', this)
})
}
}
24 changes: 24 additions & 0 deletions src/main/GameFromProcess.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import BaseGame from './BaseGame'

export default class GameFromProcess extends BaseGame {
private process: yuki.Process

constructor (process: yuki.Process) {
super()
this.process = process
this.pids = [process.pid]
}

public getInfo (): yuki.Game {
return {
name: this.process.name.replace('.exe', ''),
code: '',
path: '',
localeChanger: ''
}
}

public start () {
this.afterGetPids()
}
}
52 changes: 52 additions & 0 deletions src/main/Processes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { exec } from 'child_process'
const debug = require('debug')('yuki:processes')

export default class Processes {
public static async get () {
return new Promise<yuki.Processes>((resolve, reject) => {
exec(Processes.TASK_LIST_COMMAND,
(err, stdout, stderr) => {
if (err) {
debug('exec failed !> %s', err)
reject()
return
}

if (this.findsProcessIn(stdout)) {
const result = this.parseProcessesFrom(stdout)
debug('get %d processes', result.length)
resolve(result)
} else {
debug('exec failed. no process')
reject()
}
}
)
})
}
private static TASK_LIST_COMMAND = 'tasklist /nh /fo csv /fi "sessionname eq Console"'

private static findsProcessIn (value: string) {
return value.startsWith('"')
}

private static parseProcessesFrom (value: string) {
const processes: yuki.Processes = []

const regexResult = value.match(/"([^"]+)"/g)
if (!regexResult) return []

let onePair: yuki.Process = { name: '', pid: -1 }
for (let i = 0; i < regexResult.length; i++) {
if (i % 5 === 0) {// process name
onePair.name = regexResult[i].substr(1, regexResult[i].length - 2)
} else if (i % 5 === 1) {// process id
onePair.pid = parseInt(regexResult[i].substr(1, regexResult[i].length - 2), 10)
processes.push(onePair)
onePair = { name: '', pid: -1 }
}
}

return processes
}
}
16 changes: 11 additions & 5 deletions src/main/TranslatorWindow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BrowserWindow } from 'electron'
import BaseGame from './BaseGame'
import ConfigManager from './config/ConfigManager'
import Game from './Game'
import Hooker from './Hooker'
Expand All @@ -12,9 +13,10 @@ export default class TranslatorWindow {
: `file://${__dirname}/translator.html`

private window!: Electron.BrowserWindow
private game!: Game
private game!: BaseGame

private isRealClose = false
private config!: yuki.Config.Gui['translatorWindow']

constructor () {
this.create()
Expand All @@ -30,7 +32,7 @@ export default class TranslatorWindow {
this.window.close()
}

public setGame (game: Game) {
public setGame (game: BaseGame) {
this.game = game
}

Expand All @@ -39,6 +41,8 @@ export default class TranslatorWindow {
}

private create () {
this.config = ConfigManager.getInstance().get<yuki.Config.Gui>('gui')
.translatorWindow
this.window = new BrowserWindow({
webPreferences: {
defaultFontFamily: {
Expand All @@ -48,8 +52,7 @@ export default class TranslatorWindow {
}
},
show: false,
alwaysOnTop: ConfigManager.getInstance().get<yuki.Config.Gui>('gui')
.translatorWindow.alwaysOnTop,
alwaysOnTop: this.config.alwaysOnTop,
transparent: true,
frame: false
})
Expand All @@ -61,7 +64,10 @@ export default class TranslatorWindow {
)

this.window.on('ready-to-show', () => {
ElectronVibrancy.SetVibrancy(this.window, 0)
// choose translucent as default, unless assigning transparent explicitly
if (this.config.renderMode !== 'transparent') {
ElectronVibrancy.SetVibrancy(this.window, 0)
}

debug('subscribing hooker events...')
this.subscribeHookerEvents()
Expand Down
3 changes: 2 additions & 1 deletion src/main/config/GuiConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export default class GuiConfig extends Config {
color: 'white',
margin: 18
},
background: '#000000BD'
background: '#000000BD',
renderMode: 'translucent'
}
}
}
Expand Down
29 changes: 24 additions & 5 deletions src/main/setup/Ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import IpcTypes from '../../common/IpcTypes'
const debug = require('debug')('yuki:ipc')
import { extname } from 'path'
import { format } from 'util'
import BaseGame from '../BaseGame'
import ConfigManager from '../config/ConfigManager'
import DownloaderFactory from '../DownloaderFactory'
import Game from '../Game'
import GameFromProcess from '../GameFromProcess'
import Hooker from '../Hooker'
import Processes from '../Processes'
import DictManager from '../translate/DictManager'
import TranslationManager from '../translate/TranslationManager'
import TranslatorWindow from '../TranslatorWindow'

let runningGame: Game
let runningGame: BaseGame
let translatorWindow: TranslatorWindow | null

export default function (mainWindow: Electron.BrowserWindow) {
Expand All @@ -38,11 +41,16 @@ export default function (mainWindow: Electron.BrowserWindow) {

ipcMain.on(
IpcTypes.REQUEST_RUN_GAME,
(event: Electron.Event, game: yuki.Game) => {
mainWindow.hide()

runningGame = new Game(game)
(event: Electron.Event, game?: yuki.Game, process?: yuki.Process) => {
if (game) {
runningGame = new Game(game)
} else if (process) {
runningGame = new GameFromProcess(process)
} else return
runningGame.on('started', () => {
mainWindow.hide()
mainWindow.webContents.send(IpcTypes.HAS_RUNNING_GAME)

if (translatorWindow) translatorWindow.close()
translatorWindow = new TranslatorWindow()
translatorWindow.setGame(runningGame)
Expand Down Expand Up @@ -216,6 +224,17 @@ export default function (mainWindow: Electron.BrowserWindow) {
DownloaderFactory.makeLibraryDownloader(packName).start()
}
)

ipcMain.on(
IpcTypes.REQUEST_PROCESSES,
(event: Electron.Event) => {
Processes.get().then((processes) => {
event.sender.send(IpcTypes.HAS_PROCESSES, processes)
}).catch(() => {
event.sender.send(IpcTypes.HAS_PROCESSES, [])
})
}
)
}

function sendConfig (configName: string, event: Electron.Event) {
Expand Down
Loading

0 comments on commit a317c6f

Please sign in to comment.