Skip to content

Commit

Permalink
feat: Add basic Ruffle support
Browse files Browse the repository at this point in the history
  • Loading branch information
colin969 committed Jan 19, 2025
1 parent 348b8ed commit aa31024
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 35 deletions.
18 changes: 10 additions & 8 deletions docs/extensions/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,16 @@ However, Applications can also provide `url` or `command` instead. The full deta
{
"title": "Test Extension",
"properties": {
"title": "Test Select",
"type": "string",
"enum": [
"string1",
"string2"
],
"default": "string1",
"description": "Example of an extension config prop",
"key": {
"title": "Test Select",
"type": "string",
"enum": [
"string1",
"string2"
],
"default": "string1",
"description": "Example of an extension config prop"
}
}
}
]
Expand Down
22 changes: 21 additions & 1 deletion extensions/core-ruffle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,27 @@
"description": "Required for Ruffle playback of Flash games",
"version": "1.0.0",
"main": "./dist/extension.js",
"contributes": {},
"contributes": {
"configuration": [
{
"title": "Ruffle",
"properties": {
"com.ruffle.enabled": {
"title": "Enabled (Supported Games)",
"type": "boolean",
"default": false,
"description": "Enables Ruffle for games that have been marked as properly supported."
},
"com.ruffle.enabled-all": {
"title": "Enabled (Unsupported Games)",
"type": "boolean",
"default": false,
"description": "Enables Ruffle Standalone for all games regardless of whether they have been checked as supported. Results my vary."
}
}
}
]
},
"scripts": {
"build": "gulp build --color",
"watch": "gulp watch --color",
Expand Down
69 changes: 69 additions & 0 deletions extensions/core-ruffle/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,75 @@ export async function activate(context: flashpoint.ExtensionContext): Promise<vo
const webEmbedMiddleware = new RuffleWebEmbedMiddleware(path.join(baseDataPath, 'webhosted'));
flashpoint.middleware.registerMiddleware(webEmbedMiddleware);

const firstLaunch = !flashpoint.getExtConfigValue('com.ruffle.first-launch-complete');
if (firstLaunch) {
flashpoint.onDidConnect(async () => {
const handle = await flashpoint.dialogs.showMessageBoxWithHandle({
message: 'Do you want to enable Ruffle for supported Flash games?\nRuffle is a modern Flash emulator.\nThis may cause performance issues on weaker machines.',
largeMessage: true,
buttons: ['Yes', 'No'],
cancelId: 1
});
const res = await flashpoint.dialogs.awaitDialog(handle);
if (res.buttonIdx === 0) {
flashpoint.setExtConfigValue('com.ruffle.enabled', true);
}
flashpoint.setExtConfigValue('com.ruffle.first-launch-complete', true);
});
}

flashpoint.games.onWillLaunchGame((launchInfo) => {
const supportedEnabled = flashpoint.getExtConfigValue('com.ruffle.enabled');
const unsupportedEnabled = flashpoint.getExtConfigValue('com.ruffle.enabled-all');

if (supportedEnabled) {
if (launchInfo.game.ruffleSupport === 'Standalone') {
flashpoint.log.info('Using Standalone Ruffle for supported game...');
const defaultConfig = standaloneMiddleware.getDefaultConfig(launchInfo.game);
standaloneMiddleware.execute(launchInfo, {
middlewareId: '',
name: '',
enabled: true,
version: defaultConfig.version,
config: defaultConfig.config,
});
} else if (launchInfo.game.ruffleSupport === 'Webhosted') {
flashpoint.log.info('Using Web Embed Ruffle for supported game...');
const defaultConfig = webEmbedMiddleware.getDefaultConfig(launchInfo.game);
webEmbedMiddleware.execute(launchInfo, {
middlewareId: '',
name: '',
enabled: true,
version: defaultConfig.version,
config: defaultConfig.config,
});
}
} else if (unsupportedEnabled) {
// Get last launch arg to check if swf
let isFlash = false;
if (typeof launchInfo.launchInfo.gameArgs === 'string') {
isFlash = launchInfo.launchInfo.gameArgs.toLowerCase().endsWith('.swf');
} else if (launchInfo.launchInfo.gameArgs.length > 0) {
const gameArg = launchInfo.launchInfo.gameArgs.at(-1);
if (gameArg) {
isFlash = gameArg.toLowerCase().endsWith('.swf');
}
}

if (isFlash) {
flashpoint.log.info('Using Standalone Ruffle for unsupported game...');
const defaultConfig = standaloneMiddleware.getDefaultConfig(launchInfo.game);
standaloneMiddleware.execute(launchInfo, {
middlewareId: '',
name: '',
enabled: true,
version: defaultConfig.version,
config: defaultConfig.config,
});
}
}
});

// Check for Standalone updates
const logVoid = () => {};
const standaloneAssetFile = await getGithubAsset(getPlatformRegex(), logVoid);
Expand Down
42 changes: 21 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/react-fontawesome": "0.1.18",
"@fparchive/flashpoint-archive": "^0.9.1",
"@fparchive/flashpoint-archive": "0.10.0",
"@reduxjs/toolkit": "^2.2.6",
"@types/node-7z": "2.1.8",
"@types/react-virtualized": "^9.21.21",
Expand Down
22 changes: 22 additions & 0 deletions src/renderer/components/RightBrowseSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export class RightBrowseSidebar extends React.Component<RightBrowseSidebarProps,
onStatusClick = this.wrapOnTextClick('status');
onVersionClick = this.wrapOnTextClick('version');
onLanguageClick = this.wrapOnTextClick('language');
onRuffleSupportClick = this.wrapOnTextClick('ruffleSupport');

launchCommandRef: React.RefObject<HTMLInputElement> = React.createRef();

Expand Down Expand Up @@ -733,6 +734,27 @@ export class RightBrowseSidebar extends React.Component<RightBrowseSidebarProps,
editable={editable}
onClick={this.onLanguageClick} />
</div>
<div className='browse-right-sidebar__row browse-right-sidebar__row--one-line'>
<p>Ruffle Support: </p>
<DropdownInputField
text={game.ruffleSupport}
placeholder={'None'}
className='browse-right-sidebar__searchable'
editable={editable}
items={['None', 'Standalone']}
onItemSelect={text => {
console.log('selecting ' + text);
if (['None', 'Standalone'].includes(text)) {
this.props.onEditGame({ ruffleSupport: text as any })
}
}}
onClick={this.onRuffleSupportClick} />
{ !editable && game.ruffleSupport !== 'None' ? (
<div className='browse-right-sidebar-floating-icon'>
<OpenIcon icon='check'/>
</div>
) : undefined }
</div>
</div>
</>
{/* -- Date Display -- */}
Expand Down
5 changes: 1 addition & 4 deletions src/renderer/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1022,9 +1022,7 @@ export class App extends React.Component<AppProps> {
if (this.props.currentView.selectedGame) {
const ng = newGame();
Object.assign(ng, { ...this.props.currentView.selectedGame, ...game });
this.props.setMainState({
currentGame: ng
});
this.props.searchActions.updateGame(ng);
}
};

Expand Down Expand Up @@ -1720,7 +1718,6 @@ export class App extends React.Component<AppProps> {
};

private checkGameRunningMemo = memoizeOne((gameId: string | undefined, services: IService[]) => {
console.log('checking if running:' + gameId);
return gameId ? !!services.find(s => s.id === `game.${gameId}`) : false;
});

Expand Down
3 changes: 3 additions & 0 deletions static/window/styles/core.css
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,9 @@ body {
.browse-right-sidebar__bottom > .browse-right-sidebar__section > .browse-right-sidebar__row__screenshot-container > .browse-right-sidebar__row__screenshot> img {
height: 100%;
}
.browse-right-sidebar-floating-icon {
margin-left: 0.4rem;
}

/* Browse game stats */
.browse-right-sidebar__stats {
Expand Down
3 changes: 3 additions & 0 deletions static/window/styles/fancy.css
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,9 @@ body {
.browse-right-sidebar__game-config-dropdown-none {
font-style: italic;
}
.browse-right-sidebar-floating-icon .icon__use {
fill: var(--layout__confirm-color);
}

/* GameImageSplit */
.game-image-split {
Expand Down
2 changes: 2 additions & 0 deletions typings/flashpoint-launcher.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,8 @@ declare module 'flashpoint-launcher' {
* 2 = Available
*/
archiveState: number;
/** Ruffle support for flash entries */
ruffleSupport: 'None' | 'Standalone' | 'Webhosted';
};

type GameData = {
Expand Down

0 comments on commit aa31024

Please sign in to comment.