Skip to content

Commit b339e89

Browse files
committed
Configurable factorio directory
1 parent e1afdd5 commit b339e89

File tree

4 files changed

+128
-84
lines changed

4 files changed

+128
-84
lines changed

index.html

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<meta charset="UTF-8">
5-
<title>Hello World!</title>
6-
<link rel="stylesheet" type="text/css" href="style.css">
4+
<title>Clusterio Client</title>
5+
<link rel="stylesheet" type="text/css" href="style.css">
76
</head>
87
<body>
98
<h1>Clusterio Client</h1>
9+
<input id="folderSelector" type="submit" value="select factorio directory" onclick="mainProcess.selectFactorioDirectory()"/>
1010
<p>Master server</p>
1111
<input id="masterInput" type="text" onchange="setMasterAddress()">
12-
<!--We are using node <script>document.write(process.versions.node)</script>,
13-
Chrome <script>document.write(process.versions.chrome)</script>,
14-
and Electron <script>document.write(process.versions.electron)</script>.-->
1512
<p>Slaves:</p>
1613
<table id="slaves"></table>
1714
<script src="main.js"></script>

index.js

Lines changed: 119 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const {app, BrowserWindow, ipcMain} = require('electron')
1+
const {app, BrowserWindow, ipcMain, dialog} = require('electron')
22
const path = require('path')
33
const url = require('url')
44
const ipc = ipcMain
@@ -7,14 +7,12 @@ const child_process = require('child_process');
77
const Rcon = require('simple-rcon');
88
const http = require('http');
99
const fs = require('fs');
10+
const mkdirp = require("mkdirp");
11+
const os = require("os")
1012

1113
const Config = require('electron-config');
1214
const config = new Config();
1315

14-
// ensure default config settings
15-
if(!config.get("masterAddress")) config.set("masterAddress", "localhost:8080");
16-
17-
1816
// Keep a global reference of the window object, if you don't, the window will
1917
// be closed automatically when the JavaScript object is garbage collected.
2018
let win
@@ -64,88 +62,131 @@ app.on('activate', () => {
6462
}
6563
})
6664

67-
ipc.on('getServers', function (event, data) {
68-
//console.log(data)
69-
needle.get(config.get("masterAddress")+'/slaves', function(error, response, body) {
70-
if (!error) {
71-
event.sender.send('setServers', body)
72-
}
73-
});
74-
});
65+
// app code down here ---------------------------------------------------------
7566

76-
ipc.on("launchFactorio", function(event, data){
77-
console.log("Preparing to launch factorio with "+data.ip+":"+data.port)
78-
console.log(data.mods)
79-
80-
// RCON in to check if server is accessible
81-
var client = new Rcon({
82-
host: data.ip,
83-
port: data.rconPort,
84-
password: "thisisntarealpassword",
85-
// people who play at servers shouldn't necessarily have admin access but rcon requires a password to connect
86-
// and rcon connects even when it doesn't manage to authenticate
87-
timeout: 10, // timeout is an advantage when we only want to check if its up, if it hasn't answered in 10s its probably not there anyways
67+
app.on("ready", function() { // run main app code
68+
// ensure default config settings
69+
if(!config.get("masterAddress")) config.set("masterAddress", "localhost:8080");
70+
if(!config.get("factorioDirectory")) {
71+
console.log("Factorio directory not set!");
72+
selectFactorioDirectory();
73+
}
74+
75+
// listen for IPC signal and get JSON data from master
76+
ipc.on('getServers', function (event, data) {
77+
//console.log(data)
78+
needle.get(config.get("masterAddress")+'/slaves', function(error, response, body) {
79+
if (!error) {
80+
event.sender.send('setServers', body)
81+
}
82+
});
8883
});
89-
// start connection
90-
client.connect();
9184

92-
// when connected disconnect
93-
client.on('connected', function () {
94-
console.log('Connected!');
95-
console.log('RCON confirmed, downloading mods...');
85+
// manage and download mods, then launch factorio with a server IP
86+
ipc.on("launchFactorio", function(event, data){
87+
console.log("Preparing to launch factorio with "+data.ip+":"+data.port)
88+
console.log(data.mods)
9689

97-
// delete mods we don't want
98-
let installedMods = fs.readdirSync("factorio/mods/")
99-
for(let i = 0; i < installedMods.length; i++){
100-
let x = false;
101-
for(let key in data.mods){
102-
if(installedMods[i] == data.mods[key].modName) {
103-
x = true;
90+
// check if you chose the correct factorio directory
91+
if(os.type() == "Linux" || os.type() == "Darwin") {
92+
if(!fs.existsSync(config.get("factorioDirectory")+"/bin/x64/factorio")){
93+
console.error("ERROR: Invalid factorio directory!");
94+
console.log(config.get("factorioDirectory"));
95+
return false;
96+
} else console.log("Valid factorio directory on "+os.type());
97+
} else {// assume windows
98+
if(!fs.existsSync(config.get("factorioDirectory")+"/bin/x64/factorio.exe")){
99+
console.error("ERROR: Invalid factorio directory!");
100+
console.log(config.get("factorioDirectory"));
101+
return false;
102+
} else console.log("Valid factorio directory on "+os.type());
103+
}
104+
105+
// if this is the first run of the factorio install we need to make a mods folder
106+
mkdirp.sync(config.get("factorioDirectory")+"/mods/")
107+
108+
// RCON in to check if server is accessible
109+
var client = new Rcon({
110+
host: data.ip,
111+
port: data.rconPort,
112+
password: "thisisntarealpassword",
113+
// people who play at servers shouldn't necessarily have admin access but rcon requires a password to connect
114+
// and rcon connects even when it doesn't manage to authenticate
115+
timeout: 10, // timeout is an advantage when we only want to check if its up, if it hasn't answered in 10s its probably not there anyways
116+
});
117+
// start connection
118+
client.connect();
119+
120+
// when connected disconnect
121+
client.on('connected', function () {
122+
console.log('Connected!');
123+
console.log('RCON confirmed, downloading mods...');
124+
125+
// delete mods we don't want
126+
let installedMods = fs.readdirSync(config.get("factorioDirectory")+"/mods/")
127+
for(let i = 0; i < installedMods.length; i++){
128+
let x = false;
129+
for(let key in data.mods){
130+
if(installedMods[i] == data.mods[key].modName) {
131+
x = true;
132+
}
104133
}
105-
}
106-
if (!x) {
107-
console.log("Deleting: " + installedMods[i]);
108-
// Unlink is how you delete files in node
109-
fs.unlinkSync("factorio/mods/"+installedMods[i]);
134+
if (!x) {
135+
console.log("Deleting: " + installedMods[i]);
136+
// Unlink is how you delete files in node
137+
fs.unlinkSync(config.get("factorioDirectory")+"/mods/"+installedMods[i]);
138+
}
139+
110140
}
111141

112-
}
113-
114-
// download mods we don't have
115-
let counter = 0;
116-
for(let key in data.mods) {
117-
if(fs.existsSync("factorio/mods/"+data.mods[key].modName)){
118-
console.log("Installed: " + data.mods[key].modName);
119-
} else {
120-
console.log("Downloading: " + data.mods[key].modName);
121-
download("http://"+config.get("masterAddress")+"/"+data.mods[key].modName, "factorio/mods/"+data.mods[key].modName, launch(data.mods[key].modName));
142+
// download mods we don't have
143+
let counter = 0;
144+
for(let key in data.mods) {
145+
if(fs.existsSync(config.get("factorioDirectory")+"/mods/"+data.mods[key].modName)){
146+
console.log("Installed: " + data.mods[key].modName);
147+
launch(data.mods[key].modName);
148+
} else {
149+
console.log("Downloading: " + data.mods[key].modName);
150+
download("http://"+config.get("masterAddress")+"/"+data.mods[key].modName, config.get("factorioDirectory")+"/mods/"+data.mods[key].modName, launch(data.mods[key].modName));
151+
}
122152
}
123-
}
124-
function launch(modName) {
125-
counter++;
126-
console.log("Downloaded: " + modName);
127-
if(counter == data.mods.length) {
128-
//spawn factorio and tell it to connect to a server directly
129-
console.log("Starting factorio...");
130-
var gameprocess = child_process.spawn("factorio/bin/x64/factorio", [
131-
"--mp-connect", data.ip+":"+data.port,
132-
]);
153+
function launch(modName) {
154+
counter++;
155+
if(counter == data.mods.length) {
156+
//spawn factorio and tell it to connect to a server directly
157+
console.log("Starting factorio...");
158+
var gameprocess = child_process.spawn(config.get("factorioDirectory")+"/bin/x64/factorio", [
159+
"--mp-connect", data.ip+":"+data.port,
160+
]);
161+
}
133162
}
134-
}
135-
136-
// this causes error write_after_end, and it is kinda important but I have to leave it out
137-
//client.close(); // disconnect once we have connected because we are not actually going to rcon anything
138-
}).on('disconnected', function () {
139-
163+
164+
// this causes error write_after_end, and it is kinda important but I have to leave it out
165+
//client.close(); // disconnect once we have connected because we are not actually going to rcon anything
166+
}).on('disconnected', function () {
167+
168+
});
140169
});
141-
});
142170

143-
var download = function(url, dest, cb) {
144-
var file = fs.createWriteStream(dest);
145-
var request = http.get(url, function(response) {
146-
response.pipe(file);
147-
file.on('finish', function() {
148-
file.close(cb);
171+
var download = function(url, dest, cb) {
172+
var file = fs.createWriteStream(dest);
173+
var request = http.get(url, function(response) {
174+
response.pipe(file);
175+
file.on('finish', function() {
176+
file.close(cb);
177+
});
149178
});
150-
});
151-
}
179+
}
180+
181+
// open file dialog to let you choose your factorio install
182+
function selectFactorioDirectory() {
183+
dialog.showOpenDialog({
184+
properties: ['openDirectory']
185+
}, function(e){
186+
if(e && e[0]) {
187+
config.set('factorioDirectory', e[0]);
188+
}
189+
});
190+
}
191+
exports.selectFactorioDirectory = selectFactorioDirectory
192+
}); // end of main app code

main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ const ipc = ipcRenderer;
44
const Config = require('electron-config');
55
const config = new Config();
66

7+
const electron = require("electron");
8+
const remote = require("electron").remote;
9+
const mainProcess = remote.require("./index");
10+
711
setInterval(function(){
812
// IPC send sends text/json/whatever to index.js or anything on the nodeside that cares to listen
913
ipc.send('getServers', "plz send");

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
"electron-config": "^0.2.1",
3131
"fs": "0.0.1-security",
3232
"http": "0.0.0",
33+
"mkdirp": "^0.5.1",
3334
"needle": "^1.4.3",
35+
"os": "^0.1.1",
3436
"portscanner": "^2.1.1",
3537
"simple-rcon": "^0.3.1"
3638
}

0 commit comments

Comments
 (0)