Skip to content

Commit

Permalink
Steam Compatibility via a new proxy mode (#510)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xzandro authored Feb 12, 2024
1 parent 6d519dd commit 4175c6f
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 55 deletions.
106 changes: 95 additions & 11 deletions app/components/Head.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import React from 'react';

import { Menu, Button, Input, Select } from 'semantic-ui-react';
import {
Divider,
Grid,
GridColumn,
GridRow,
Header,
Icon,
Menu,
Modal,
ModalContent,
ModalHeader,
Button,
Input,
Segment,
Select,
} from 'semantic-ui-react';

const { ipcRenderer } = require('electron');
const remote = require('@electron/remote');
Expand All @@ -10,7 +25,7 @@ let config = remote.getGlobal('config');
class Head extends React.Component {
constructor() {
super();
this.state = { proxyRunning: ipcRenderer.sendSync('proxyIsRunning') };
this.state = { proxyRunning: ipcRenderer.sendSync('proxyIsRunning'), modal: false };

Mousetrap.bind(['command+s', 'ctrl+s'], () => {
this.toggleProxy();
Expand Down Expand Up @@ -40,6 +55,11 @@ class Head extends React.Component {
}
}

startProxy(state) {
ipcRenderer.send('proxyStart', state);
this.setState({ modal: false });
}

getCert() {
ipcRenderer.send('getCert');
}
Expand All @@ -50,24 +70,88 @@ class Head extends React.Component {
ipcRenderer.send('updateConfig');
}

isSteamMode() {
return remote.process.platform === 'win32' && config.Config.Proxy.steamMode;
}

isWindows() {
return remote.process.platform === 'win32';
}

changeSteamMode(state) {
ipcRenderer.send('changeSteamMode', state);
}

modalSetOpen(state) {
this.setState({ modal: state });
}

render() {
const interfaces = ipcRenderer.sendSync('proxyGetInterfaces').map((interfaceEntry, i) => ({ key: i, text: interfaceEntry, value: i }));
return (
<Menu className="main-menu" fixed="top">
<Menu.Item>
<Select label="Interfaces" options={interfaces} defaultValue={0} />
</Menu.Item>
{!this.isSteamMode() && (
<Menu.Item>
<Select label="Interfaces" options={interfaces} defaultValue={0} />
</Menu.Item>
)}
<Menu.Item>
<Input label="Port" defaultValue={config.Config.Proxy.port} onChange={this.changePort.bind(this)} />
</Menu.Item>

<Menu.Item position="right">
<Button content="Get Cert" icon="share" labelPosition="right" onClick={this.getCert.bind(this)} />
<Button
content={this.state.proxyRunning ? 'Stop Proxy' : 'Start Proxy'}
icon={this.state.proxyRunning ? 'stop' : 'play'}
labelPosition="right"
onClick={this.toggleProxy.bind(this)}
/>

{this.state.proxyRunning ? (
<Button content="Stop Proxy" icon="stop" labelPosition="right" onClick={this.toggleProxy.bind(this)} />
) : this.isWindows() ? (
<Modal
onClose={() => this.modalSetOpen(false)}
onOpen={() => this.modalSetOpen(true)}
open={this.state.modal}
size="small"
trigger={<Button content="Start Proxy" icon="play" labelPosition="right" />}
>
<ModalHeader>Select a proxy mode</ModalHeader>
<ModalContent>
<Segment placeholder>
<Grid columns={2} stackable textAlign="center">
<Divider vertical>Or</Divider>

<GridRow verticalAlign="middle">
<GridColumn>
<Header icon>
<Icon name="game" />
Steam Mode
</Header>
<p>Best mode if you plan to use with the Steam version of Summoners War.</p>
<Button primary onClick={() => this.startProxy(true)}>
Start
</Button>
</GridColumn>

<GridColumn>
<Header icon>
<Icon name="world" />
Remote Mode
</Header>
<p>Default mode for anything else than the Steam version of SW, like your phone or emulators.</p>
<Button primary onClick={() => this.startProxy(false)}>
Start
</Button>
</GridColumn>
</GridRow>
<GridRow verticalAlign="middle">
<GridColumn></GridColumn>
</GridRow>
</Grid>
</Segment>
<p>For further instructions, please go to the Help section.</p>
</ModalContent>
</Modal>
) : (
<Button content="Start Proxy" icon="play" labelPosition="right" onClick={() => this.startProxy(false)} />
)}
</Menu.Item>
</Menu>
);
Expand Down
33 changes: 26 additions & 7 deletions app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const { object, string, number, date } = require('yup');
const { parse } = require('yaml');
const { validate, compare } = require('compare-versions');
const SWProxy = require('./proxy/SWProxy');
const transparentProxy = require('./steamproxy/transparent_proxy');
const proxy = new SWProxy(transparentProxy);

const path = require('path');
const url = require('url');
Expand Down Expand Up @@ -41,7 +43,7 @@ let defaultConfig = {
minimizeToTray: false,
autoUpdatePlugins: true,
},
Proxy: { port: 8080, autoStart: false },
Proxy: { port: 8080, autoStart: false, steamMode: true },
Plugins: {},
},
};
Expand All @@ -55,13 +57,15 @@ let defaultConfigDetails = {
minimizeToTray: { label: 'Minimize to System Tray' },
autoUpdatePlugins: { label: 'Auto update plugins (if supported)' },
},
Proxy: { autoStart: { label: 'Start proxy automatically' } },
Proxy: { autoStart: { label: 'Start proxy automatically' }, steamMode: { label: 'Steam Mode' } },
Plugins: {},
},
};

const updatedPluginsFolder = path.join(app.getPath('temp'), 'SWEX', 'plugins');

let quitting = false;

function createWindow() {
let mainWindowState = windowStateKeeper({
defaultWidth: 800,
Expand Down Expand Up @@ -143,8 +147,6 @@ function createWindow() {
});
}

const proxy = new SWProxy();

proxy.on('error', () => {});

ipcMain.on('proxyIsRunning', (event) => {
Expand All @@ -155,8 +157,16 @@ ipcMain.on('proxyGetInterfaces', (event) => {
event.returnValue = proxy.getInterfaces();
});

ipcMain.on('proxyStart', () => {
proxy.start(config.Config.Proxy.port);
ipcMain.on('proxyStart', (event, steamMode) => {
proxy.start(config.Config.Proxy.port, steamMode);
if (steamMode !== config.Config.Proxy.steamMode) {
config.Config.Proxy.steamMode = steamMode;
storage.set('Config', config.Config, (error) => {
if (error) throw error;

win.webContents.send('steamModeChanged', steamMode);
});
}
});

ipcMain.on('proxyStop', () => {
Expand Down Expand Up @@ -428,7 +438,7 @@ app.on('ready', async () => {
updatePlugins(global.plugins);

if (process.env.autostart || global.config.Config.Proxy.autoStart) {
proxy.start(process.env.port || config.Config.Proxy.port);
proxy.start(process.env.port || config.Config.Proxy.port, config.Config.Proxy.steamMode);
}
});
});
Expand All @@ -448,3 +458,12 @@ app.on('activate', () => {
createWindow();
}
});

app.on('before-quit', async (event) => {
if (config.Config.Proxy.steamMode && process.platform == 'win32' && !quitting) {
event.preventDefault();
quitting = true;
await proxy.removeHostsModifications();
app.quit();
}
});
84 changes: 80 additions & 4 deletions app/pages/Help.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ class Help extends React.Component {
<div>
<h1>Setup Instructions</h1>
<p>
Your computer and mobile device must be connected to the same network and be able to communicate. This is normally as simple as connecting
to the same Wi-Fi network or router. In some situations, like a college campus Wi-Fi connection, it might not work.
The following is mostly for the remote proxy mode: Your computer and mobile device must be connected to the same network and be able to
communicate. This is normally as simple as connecting to the same Wi-Fi network or router. In some situations, like a college campus Wi-Fi
connection, it might not work.
</p>
<p>
In the dropdown menu in the top left of this program, there is a list of IP addresses and a port number. If there is more than 1 IP address,
Expand Down Expand Up @@ -90,13 +91,53 @@ class Help extends React.Component {
</ul>
</Accordion.Content>

<Accordion.Title active={activeIndex === 201} index={201} onClick={this.handleAccordionClick.bind(this)}>
<Icon name="dropdown" />
Steam Mode Setup
</Accordion.Title>
<Accordion.Content active={activeIndex === 201}>
<p>
Steam mode might be the easiest way to get your JSON file if you use Windows and actually do use the Steam version of Summoners War.
Make sure when you start the proxy to choose Steam mode. (Windows only)
</p>
<p>
This also requires Admin permissions when you start AND stop the proxy. The reason is, that we do modification to the hosts file. Some
security software could recognize this as malicious activity, so make sure to act accordingly and grant SWEX access to do that.
</p>
<p>Additionally, make sure to keep other software like Proxyfier off during the process, it is not needed.</p>
<p>
After starting the proxy in Steeam mode, you only need to do one instruction; installing the cert to the Windoed trusted root storage.
</p>
<ol>
<li> SWEX get cert </li>
<li>
Install certificate to the TrustedRoot certificate storage of Windows.
<ul>
<li>
You could look at{' '}
<a
href="https://asu.my.salesforce-sites.com/kb/articles/FAQ/How-Do-I-Add-Certificates-to-the-Trusted-Root-Certification-Authorities-Store-for-a-Local-Computer"
target="_blank"
>
this guide.
</a>
</li>
<li>You can skip to step 7, if you hit the Windows key and search for "certificate" to then go to "Manage User Certificates"</li>
<li>Continue following the guide.</li>
</ul>
</li>
<li> In SWEX: confirm HTTPS is turned on</li>
<li> In SWEX: make sure SWEX is running in Steam Mode.</li>
</ol>
</Accordion.Content>

<Accordion.Title active={activeIndex === 2} index={2} onClick={this.handleAccordionClick.bind(this)}>
<Icon name="dropdown" />
Mumu Setup
Mumu 6 Setup
</Accordion.Title>
<Accordion.Content active={activeIndex === 2}>
<a href="https://drive.google.com/file/d/1mQuivBo2lpRvPI4Obapvcb9NYDcaSUoh/view" target="_blank">
Mumu setup guide
Mumu 6 setup guide
</a>
<ol>
<li> SWEX get cert </li>
Expand All @@ -120,6 +161,41 @@ class Help extends React.Component {
</ol>
</Accordion.Content>

<Accordion.Title active={activeIndex === 200} index={200} onClick={this.handleAccordionClick.bind(this)}>
<Icon name="dropdown" />
Mumu 12 Setup
</Accordion.Title>
<Accordion.Content active={activeIndex === 200}>
<ol>
<li> SWEX get cert </li>
<li> Open mumu shared folder</li>
<li> Copy cert from your SWEX files folder into the MuMuSharedFolder.</li>
<li>
Navigate to: System Application folder → Settings → Network & Internet → Internet → Network preferences → Install certificates →
$MuMuSharedFolder
</li>
<li>
Navigate to: System Application folder → Settings → Network & Internet → Internet → Network preferences → Install certificates →
$MuMuSharedFolder
<ul>
<li>If the cert file is greyed out for some reason try to rename the extension from .pem to .cer</li>
</ul>
</li>
<li> Back to Internet Menu</li>
<li> Click the active connection → pen icon in the top right</li>
<li> Start the proxy in SWEX (if not already done)</li>
<li> Change "Proxy" to "Manual"</li>
<li>
Server: ip listed in the top left of SWEX, usually one of 192.168.x.x / 172.16.x.x / 10.x.x.x; Port: Port listed in SWEX, default =
8080
</li>
<li> Fill out the port. Otherwise this change is not saved.</li>
<li> Press Save</li>
<li> In SWEX: confirm HTTPS is turned on</li>
<li> In SWEX: Start proxy</li>
</ol>
</Accordion.Content>

<Accordion.Title active={activeIndex === 3} index={3} onClick={this.handleAccordionClick.bind(this)}>
<Icon name="dropdown" />
Nox Setup
Expand Down
2 changes: 1 addition & 1 deletion app/pages/Logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const STATUS_COLOR_MAP = {
info: 'blue',
warning: 'yellow',
error: 'red',
debug: 'darkgrey',
debug: 'grey',
};
const STATUS_ICON_MAP = {
success: 'check',
Expand Down
3 changes: 3 additions & 0 deletions app/pages/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class Settings extends React.Component {
<Form.Group widths={2}>
<Button content="Regenerate Cert" icon="refresh" size="small" labelPosition="left" onClick={this.openCertCinfirmDialog.bind(this)} />
</Form.Group>
<Form.Group widths={2}>
<SettingsItem section="Proxy" setting="steamMode" type="checkbox" />
</Form.Group>
</Form>
</Segment>

Expand Down
Loading

0 comments on commit 4175c6f

Please sign in to comment.