Skip to content

Commit

Permalink
Merge branch 'hotfix/10.1.7'
Browse files Browse the repository at this point in the history
  • Loading branch information
colin969 committed Oct 1, 2022
2 parents 9937201 + e976f3e commit 0289b4d
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 137 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ npm-debug.log.*

# Visual Studio Code
/.vscode
/.vs

# JetBrains
/.idea
Expand Down
268 changes: 186 additions & 82 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flashpoint-launcher",
"version": "10.1.6",
"version": "10.1.7",
"description": "A desktop application used to browse, manage and play games from BlueMaxima's Flashpoint",
"main": "build/main/index.js",
"config": {
Expand Down Expand Up @@ -95,7 +95,7 @@
"chokidar": "^3.5.3",
"coveralls": "3.1.0",
"cross-env": "7.0.2",
"electron": "19.0.10",
"electron": "19.1.0",
"electron-builder": "22.14.13",
"electron-devtools-installer": "3.1.1",
"eslint": "7.2.0",
Expand All @@ -105,7 +105,7 @@
"jest": "28.1.0",
"swc-loader": "0.2.3",
"ts-jest": "28.0.3",
"ts-loader": "9.3.0",
"ts-loader": "9.4.1",
"ts-node": "10.8.0",
"ts-transform-paths": "^2.0.3",
"tsconfig-paths-webpack-plugin": "3.2.0",
Expand All @@ -114,8 +114,8 @@
"ttypescript": "^1.5.13",
"typedoc": "0.22.15",
"typescript": "4.6.2",
"webpack": "5.72.1",
"webpack-cli": "4.9.2"
"webpack": "5.74.0",
"webpack-cli": "4.10.0"
},
"optionalDependencies": {
"fsevents": "2.1.3"
Expand Down
31 changes: 19 additions & 12 deletions src/back/GameLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type LaunchBaseOpts = {
appPathOverrides: AppPathOverride[];
providers: AppProvider[];
proxy: string;
envPATH?: string;
openDialog: ShowMessageBoxFunc;
openExternal: OpenExternalFunc;
runGame: (gameLaunchInfo: GameLaunchInfo) => ManagedChildProcess;
Expand Down Expand Up @@ -97,7 +98,7 @@ export namespace GameLauncher {
gamePath: appPath,
gameArgs: appArgs,
useWine,
env: getEnvironment(opts.fpPath, opts.proxy),
env: getEnvironment(opts.fpPath, opts.proxy, opts.envPATH),
};
const proc = exec(
createCommand(launchInfo),
Expand Down Expand Up @@ -137,7 +138,8 @@ export namespace GameLauncher {
proxy: opts.proxy,
openDialog: opts.openDialog,
openExternal: opts.openExternal,
runGame: opts.runGame
runGame: opts.runGame,
envPATH: opts.envPATH
};
for (const addApp of opts.game.addApps) {
if (addApp.autoRunBefore) {
Expand Down Expand Up @@ -187,7 +189,7 @@ export namespace GameLauncher {

// Browser Mode Launch
if (isBrowserOpts(res)) {
const env = getEnvironment(opts.fpPath, opts.proxy);
const env = getEnvironment(opts.fpPath, opts.proxy, opts.envPATH);
if ('ELECTRON_RUN_AS_NODE' in env) {
delete env['ELECTRON_RUN_AS_NODE']; // If this flag is present, it will disable electron features from the process
}
Expand Down Expand Up @@ -232,7 +234,7 @@ export namespace GameLauncher {
const gamePath: string = path.isAbsolute(appPath) ? fixSlashes(appPath) : fixSlashes(path.join(opts.fpPath, appPath));
const gameArgs: string[] = [...appArgs, opts.game.launchCommand];
const useWine: boolean = process.platform != 'win32' && gamePath.endsWith('.exe');
const env = getEnvironment(opts.fpPath, opts.proxy);
const env = getEnvironment(opts.fpPath, opts.proxy, opts.envPATH);
try {
await GameManager.findGame(opts.game.id);
} catch (err: any) {
Expand Down Expand Up @@ -300,17 +302,22 @@ export namespace GameLauncher {
}

/** Get an object containing the environment variables to use for the game / additional application. */
function getEnvironment(fpPath: string, proxy: string): NodeJS.ProcessEnv {
// When using Linux, use the proxy created in BackgroundServices.ts
// This is only needed on Linux because the proxy is installed on system
// level entire system when using Windows.
// When using WINE on mac, the proxy variable is needed as well.
function getEnvironment(fpPath: string, proxy: string, path?: string): NodeJS.ProcessEnv {
let newEnvVars: NodeJS.ProcessEnv = {'FP_PATH': fpPath, 'PATH': path ?? process.env.PATH};
// On Linux, we tell native applications to use Flashpoint's proxy using the HTTP_PROXY env var
// On Windows, executables are patched to load the FlashpointProxy library
// On Linux/Mac, WINE obeys the HTTP_PROXY env var so we can run unpatched Windows executables
if (process.platform === 'linux' || process.platform === 'darwin') {
// Add proxy env vars and prevent WINE from flooding the logs with debug messages
newEnvVars = {
...newEnvVars, 'WINEDEBUG': 'fixme-all',
...(proxy !== '' ? {'http_proxy': `http://${proxy}/`, 'HTTP_PROXY': `http://${proxy}/`} : null)
};
}
return {
'FP_PATH': fpPath,
// Add proxy env vars if it's running on linux
...(((process.platform === 'linux' || process.platform === 'darwin') && proxy !== '') ? { http_proxy: `http://${proxy}/`, HTTP_PROXY: `http://${proxy}/` } : null),
// Copy this processes environment variables
...process.env,
...newEnvVars
};
}

Expand Down
17 changes: 0 additions & 17 deletions src/back/ManagedChildProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,6 @@ export class ManagedChildProcess extends EventEmitter {
this.autoRestartCount = 0;
}
// Spawn process
if (process.platform == 'darwin') {
if (this.env === undefined) {
this.env = {};
}
if (this.env.PATH === undefined) {
this.env.PATH = '';
}
const pathArr: string[] = this.env.PATH.split(':');
// HACK: manually read in /etc/paths to PATH. Needs to be done on Mac, because otherwise
// the brew path won't be found.
for (const entry of readFileSync('/etc/paths').toString().split('\n')) {
if (entry != '' && !pathArr.includes(entry)) {
pathArr.push(entry);
}
}
this.env.PATH = pathArr.join(':');
}
this.process = spawn(this.info.filename, this.info.arguments, { cwd: this.cwd, detached: this.detached, shell: this.shell , env: this.env});
// Set start timestamp
this.startTime = Date.now();
Expand Down
53 changes: 46 additions & 7 deletions src/back/game/GameManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,13 @@ export async function removePlaylistGame(playlistId: string, gameId: string): Pr
const playlistGame = await findPlaylistGame(playlistId, gameId);
if (playlistGame) {
onDidRemovePlaylistGame.fire(playlistGame);
return playlistGameRepository.remove(playlistGame);
await playlistGameRepository.remove(playlistGame);

const playlistRepository = AppDataSource.getRepository(Playlist);
const playlist = await playlistRepository.findOneBy({ id: playlistId });
if (playlist) {
onDidUpdatePlaylist.fire({ oldPlaylist: playlist, newPlaylist: playlist });
}
}
return null;
}
Expand All @@ -408,19 +414,34 @@ export async function addPlaylistGame(playlistId: string, gameId: string): Promi
.select('pg.order')
.getOne();

await repository.save<PlaylistGame>({
const pg = await repository.save<PlaylistGame>({
gameId: gameId,
playlistId: playlistId,
order: highestOrder ? highestOrder.order + 1 : 0,
notes: '',
});

onDidUpdatePlaylistGame.fire({oldGame: pg, newGame: pg});
const playlistRepository = AppDataSource.getRepository(Playlist);
const playlist = await playlistRepository.findOneBy({ id: playlistId });
if (playlist) {
onDidUpdatePlaylist.fire({ oldPlaylist: playlist, newPlaylist: playlist });
}

}

/** Updates a Playlist Game */
export async function updatePlaylistGame(playlistGame: PlaylistGame): Promise<PlaylistGame> {
const playlistGameRepository = AppDataSource.getRepository(PlaylistGame);
const savedPlaylistGame = await playlistGameRepository.save(playlistGame);
if (savedPlaylistGame) { onDidUpdatePlaylistGame.fire({oldGame: playlistGame, newGame: savedPlaylistGame }); }
onDidUpdatePlaylistGame.fire({oldGame: playlistGame, newGame: savedPlaylistGame });

const playlistRepository = AppDataSource.getRepository(Playlist);
const playlist = await playlistRepository.findOneBy({ id: savedPlaylistGame.playlistId });
if (playlist) {
onDidUpdatePlaylist.fire({ oldPlaylist: playlist, newPlaylist: playlist });
}

return savedPlaylistGame;
}

Expand Down Expand Up @@ -557,15 +578,33 @@ async function applyTagFilters(aliases: string[], alias: string, query: SelectQu
.select('tag_alias.tagId')
.distinct();

const subQuery = AppDataSource.createQueryBuilder()
let subQueryTwo = undefined;
if (whitelist) {
subQueryTwo = AppDataSource.createQueryBuilder()
.select('game_tag.gameId, COUNT(*) as count')
.from('game_tags_tag', 'game_tag')
.where(`game_tag.tagId IN (${tagIdQuery.getQuery()})`)
.groupBy('game_tag.gameId');
}

let subQuery = AppDataSource.createQueryBuilder()
.select('game_tag.gameId')
.distinct()
.from('game_tags_tag', 'game_tag')
.where(`game_tag.tagId IN (${tagIdQuery.getQuery()})`);
.distinct();

if (subQueryTwo) {
subQuery = subQuery.from(`(${subQueryTwo.getQuery()})`, 'game_tag')
.where(`game_tag.count == ${aliases.length}`);
} else {
subQuery = subQuery.from('game_tags_tag', 'game_tag')
.where(`game_tag.tagId IN (${tagIdQuery.getQuery()})`);
}

query.andWhere(`${alias}.id ${comparator} (${subQuery.getQuery()})`);
query.setParameters(subQuery.getParameters());
query.setParameters(tagIdQuery.getParameters());
if (subQueryTwo) {
query.setParameters(subQueryTwo.getParameters());
}
}

async function getGameQuery(
Expand Down
23 changes: 20 additions & 3 deletions src/back/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import { EventQueue } from './util/EventQueue';
import { FolderWatcher } from './util/FolderWatcher';
import { LogFile } from './util/LogFile';
import { logFactory } from './util/logging';
import { createContainer, exit, runService } from './util/misc';
import { createContainer, exit, getMacPATH, runService } from './util/misc';

const dataSourceOptions: DataSourceOptions = {
type: 'better-sqlite3',
Expand Down Expand Up @@ -339,6 +339,12 @@ async function onProcessMessage(message: any, sendHandle: any): Promise<void> {

console.log('Back - Loaded Preferences');

let pathReadPromise: Promise<string> | undefined = undefined;
if (process.platform === 'darwin') {
pathReadPromise = getMacPATH();
console.log('Back - Started Mac PATH-reading');
}

try {
const [extConf] = await (Promise.all([
ExtConfigFile.readOrCreateFile(path.join(state.config.flashpointPath, EXT_CONFIG_FILENAME))
Expand Down Expand Up @@ -406,6 +412,11 @@ async function onProcessMessage(message: any, sendHandle: any): Promise<void> {

console.log('Back - Initialized Database');

if (pathReadPromise) {
state.pathVar = await pathReadPromise;
console.log('Back - Got Mac PATH');
}

// Init extensions
const addExtLogFactory = (extId: string) => (entry: ILogEntry) => {
state.extensionsService.logExtension(extId, entry);
Expand Down Expand Up @@ -469,13 +480,19 @@ async function onProcessMessage(message: any, sendHandle: any): Promise<void> {
// Run processes
if (state.serviceInfo.server.length > 0) {
const chosenServer = state.serviceInfo.server.find(i => i.name === state.config.server);
runService(state, 'server', 'Server', state.config.flashpointPath, {}, chosenServer || state.serviceInfo.server[0]);
runService(state, 'server', 'Server', state.config.flashpointPath, {env: {
...process.env,
'PATH': state.pathVar ?? process.env.PATH,
}}, chosenServer || state.serviceInfo.server[0]);
}
// Start daemons
for (let i = 0; i < state.serviceInfo.daemon.length; i++) {
const service = state.serviceInfo.daemon[i];
const id = 'daemon_' + i;
runService(state, id, service.name || id, state.config.flashpointPath, {}, service);
runService(state, id, service.name || id, state.config.flashpointPath, {env: {
...process.env,
'PATH': state.pathVar ?? process.env.PATH,
}}, service);
}
// Start file watchers
for (let i = 0; i < state.serviceInfo.watch.length; i++) {
Expand Down
27 changes: 18 additions & 9 deletions src/back/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ export function registerRequestCallbacks(state: BackState): void {
proxy: state.preferences.browserModeProxy,
openDialog: state.socketServer.showMessageBoxBack(event.client),
openExternal: state.socketServer.openExternal(event.client),
runGame: runGameFactory(state)
runGame: runGameFactory(state),
envPATH: state.pathVar,
});
state.apiEmitters.games.onDidLaunchAddApp.fire(addApp);
}
Expand All @@ -266,10 +267,6 @@ export function registerRequestCallbacks(state: BackState): void {
state.socketServer.register(BackIn.LAUNCH_GAME, async (event, id) => {
const game = await GameManager.findGame(id);

await new Promise<void>((resolve) => {
setTimeout(resolve, 5000);
});

if (game) {
// Make sure Server is set to configured server - Curations may have changed it
const configServer = state.serviceInfo ? state.serviceInfo.server.find(s => s.name === state.config.server) : undefined;
Expand All @@ -278,7 +275,10 @@ export function registerRequestCallbacks(state: BackState): void {
if (!server || !('name' in server.info) || server.info.name !== configServer.name) {
// Server is different, change now
if (server) { await removeService(state, 'server'); }
runService(state, 'server', 'Server', state.config.flashpointPath, {}, configServer);
runService(state, 'server', 'Server', state.config.flashpointPath, {env: {
...process.env,
'PATH': state.pathVar ?? process.env.PATH,
}}, configServer);
}
}
log.debug('TEST', 'Server change done');
Expand Down Expand Up @@ -329,6 +329,7 @@ export function registerRequestCallbacks(state: BackState): void {
openDialog: state.socketServer.showMessageBoxBack(event.client),
openExternal: state.socketServer.openExternal(event.client),
runGame: runGameFactory(state),
envPATH: state.pathVar,
},
state.apiEmitters.games.onWillLaunchGame);
await state.apiEmitters.games.onDidLaunchGame.fire(game);
Expand Down Expand Up @@ -1075,11 +1076,17 @@ export function registerRequestCallbacks(state: BackState): void {
// Set the content folder path as the final parameter
mad4fpServerCopy.arguments.push(getContentFolderByKey(data.key, state.config.flashpointPath));
await removeService(state, 'server');
runService(state, 'server', 'Server', state.config.flashpointPath, {}, mad4fpServerCopy);
runService(state, 'server', 'Server', state.config.flashpointPath, {env: {
...process.env,
'PATH': state.pathVar ?? process.env.PATH,
}}, mad4fpServerCopy);
} else if (!data.mad4fp && activeServerInfo && activeServerInfo.mad4fp && !configServer.mad4fp) {
// Swap to mad4fp server
await removeService(state, 'server');
runService(state, 'server', 'Server', state.config.flashpointPath, {}, configServer);
runService(state, 'server', 'Server', state.config.flashpointPath, {env: {
...process.env,
'PATH': state.pathVar ?? process.env.PATH,
}}, configServer);
}
}
}
Expand All @@ -1098,6 +1105,7 @@ export function registerRequestCallbacks(state: BackState): void {
openDialog: state.socketServer.showMessageBoxBack(event.client),
openExternal: state.socketServer.openExternal(event.client),
runGame: runGameFactory(state),
envPATH: state.pathVar,
},
state.apiEmitters.games.onWillLaunchCurationGame,
state.apiEmitters.games.onDidLaunchCurationGame);
Expand All @@ -1124,6 +1132,7 @@ export function registerRequestCallbacks(state: BackState): void {
openDialog: state.socketServer.showMessageBoxBack(event.client),
openExternal: state.socketServer.openExternal(event.client),
runGame: runGameFactory(state),
envPATH: state.pathVar,
},
state.apiEmitters.games.onWillLaunchCurationAddApp,
state.apiEmitters.games.onDidLaunchCurationAddApp);
Expand All @@ -1134,7 +1143,7 @@ export function registerRequestCallbacks(state: BackState): void {

state.socketServer.register(BackIn.OPEN_LOGS_WINDOW, async (event) => {
if (!state.services.has('logger_window')) {
const env = process.env;
const env: NodeJS.ProcessEnv = {...process.env, 'PATH': state.pathVar ?? process.env.PATH};
if ('ELECTRON_RUN_AS_NODE' in env) {
delete env['ELECTRON_RUN_AS_NODE']; // If this flag is present, it will disable electron features from the process
}
Expand Down
1 change: 1 addition & 0 deletions src/back/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type BackState = {
extensionsService: ExtensionService;
prefsQueue: EventQueue;
logsWindowProc?: ManagedChildProcess;
pathVar?: string;
}

export type BackQueryChache = {
Expand Down
Loading

0 comments on commit 0289b4d

Please sign in to comment.