Add a "to do" list in README.md and implement config reader/writer
This commit is contained in:
		| @@ -3,3 +3,8 @@ | |||||||
| A Plutonium launcher that aims to make old CoD games more accessible | A Plutonium launcher that aims to make old CoD games more accessible | ||||||
| ----- | ----- | ||||||
| Currently being written from scratch, please be patient. | Currently being written from scratch, please be patient. | ||||||
|  |  | ||||||
|  | ## To do | ||||||
|  | - Make each HTTPS request its own function instead of binding them to an event | ||||||
|  | - De-duplicate code (HTTPS requests in src/main.js for example) | ||||||
|  | - Make a better UI/UX | ||||||
|   | |||||||
							
								
								
									
										126
									
								
								src/main.js
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								src/main.js
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| const path = require("node:path"); | const path = require("node:path"); | ||||||
| const fs = require("node:fs"); | const fs = require("node:fs"); | ||||||
|  | const fsPromises = require("node:fs/promises"); | ||||||
| const https = require("node:https"); | const https = require("node:https"); | ||||||
| const process = require("node:process"); | const process = require("node:process"); | ||||||
| const os = require("node:os"); | const os = require("node:os"); | ||||||
| @@ -43,6 +44,15 @@ let userInfo = { | |||||||
| 	"emailVerified": false, | 	"emailVerified": false, | ||||||
| 	"avatar": "https://forum.plutonium.pw/assets/uploads/system/avatar-default.png" | 	"avatar": "https://forum.plutonium.pw/assets/uploads/system/avatar-default.png" | ||||||
| }; | }; | ||||||
|  | let config = { | ||||||
|  | 	"user-info": userInfo, | ||||||
|  | 	"game-directories": { | ||||||
|  | 		"iw5": "", | ||||||
|  | 		"t4": "", | ||||||
|  | 		"t5": "", | ||||||
|  | 		"t6": "" | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
| function createMainWindow() { | function createMainWindow() { | ||||||
| 	mainWindow = new electron.BrowserWindow({ | 	mainWindow = new electron.BrowserWindow({ | ||||||
| @@ -65,6 +75,34 @@ function createMainWindow() { | |||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function readConfig(filePath) { | ||||||
|  | 	return new Promise(function (resolve, reject) { | ||||||
|  | 		if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) return reject(new Error("Config file doesn't exist or is not a file.")); | ||||||
|  |  | ||||||
|  | 		fsPromises.readFile(filePath, "utf-8").then(function (contents) { | ||||||
|  | 			try { | ||||||
|  | 				let data = JSON.parse(contents); | ||||||
|  |  | ||||||
|  | 				resolve(data); | ||||||
|  | 			} catch (error) { | ||||||
|  | 				reject(error); | ||||||
|  | 			} | ||||||
|  | 		}).catch(function (error) { | ||||||
|  | 			reject(error); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function writeConfig(filePath, data = {}) { | ||||||
|  | 	return new Promise(function (resolve, reject) { | ||||||
|  | 		fsPromises.writeFile(filePath, JSON.stringify(data, null, "\t")).then(function () { | ||||||
|  | 			resolve(); | ||||||
|  | 		}).catch(function (error) { | ||||||
|  | 			reject(error); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
| function fetchPlutoniumManifest() { | function fetchPlutoniumManifest() { | ||||||
| 	return new Promise(function (resolve, reject) { | 	return new Promise(function (resolve, reject) { | ||||||
| 		let request = https.request("https://cdn.plutonium.pw/updater/prod/info.json", { | 		let request = https.request("https://cdn.plutonium.pw/updater/prod/info.json", { | ||||||
| @@ -99,6 +137,62 @@ function fetchPlutoniumManifest() { | |||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function validatePlutoniumLogin(token) { | ||||||
|  | 	return new Promise(function (resolve, reject) { | ||||||
|  | 		let request = https.request("https://nix.plutonium.pw/api/auth/validate", { | ||||||
|  | 			"method": "GET", | ||||||
|  | 			"headers": { | ||||||
|  | 				"Content-Length": 0, | ||||||
|  | 				"Authorization": "UserToken " + token, | ||||||
|  | 				"X-Plutonium-Revision": String(plutoniumManifest.revision), | ||||||
|  | 				"User-Agent": "Nix/3.0" | ||||||
|  | 			} | ||||||
|  | 		}, function (response) { | ||||||
|  | 			if (response.statusCode !== 200) { | ||||||
|  | 				return resolve({ | ||||||
|  | 					"status": "unauthenticated", | ||||||
|  | 					"successful": false | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			response.setEncoding("utf-8"); | ||||||
|  |  | ||||||
|  | 			let body = ""; | ||||||
|  | 			response.on("data", function (chunk) { | ||||||
|  | 				body += chunk; | ||||||
|  | 			}); | ||||||
|  | 			response.on("end", function () { | ||||||
|  | 				try { | ||||||
|  | 					let data = JSON.parse(body); | ||||||
|  |  | ||||||
|  | 					if (!("userId" in data)) { | ||||||
|  | 						reject(new Error("Authentication seems to be successful but no user identifier was returned.")); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					resolve({ | ||||||
|  | 						"status": "authenticated", | ||||||
|  | 						"successful": true, | ||||||
|  | 						...data | ||||||
|  | 					}); | ||||||
|  |  | ||||||
|  | 					userInfo = { | ||||||
|  | 						"token": token, | ||||||
|  | 						...data | ||||||
|  | 					}; | ||||||
|  | 				} catch (error) { | ||||||
|  | 					reject(error); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		request.on("error", function (error) { | ||||||
|  | 			reject(error); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		request.end(); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
| function getPlutoniumSession(game, token) { | function getPlutoniumSession(game, token) { | ||||||
| 	return new Promise(function (resolve, reject) { | 	return new Promise(function (resolve, reject) { | ||||||
| 		let payload = JSON.stringify({ | 		let payload = JSON.stringify({ | ||||||
| @@ -180,6 +274,7 @@ function launch(plutoniumInstallDirectory, game, gameInstallDirectory, online) { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			let gameProcess = child_process.spawn(bootstrapperBinary, bootstrapperArguments, { | 			let gameProcess = child_process.spawn(bootstrapperBinary, bootstrapperArguments, { | ||||||
|  | 				"cwd": plutoniumInstallDirectory, | ||||||
| 				"detached": true, | 				"detached": true, | ||||||
| 				"stdio": "ignore" | 				"stdio": "ignore" | ||||||
| 			}); | 			}); | ||||||
| @@ -201,6 +296,33 @@ electron.app.once("ready", function () { | |||||||
| 	}).catch(function (error) { | 	}).catch(function (error) { | ||||||
| 		electron.dialog.showErrorBox("Error", "The Plutonium launcher manifest could not be fetched, auto-updating might not be possible.\n" + error.message); | 		electron.dialog.showErrorBox("Error", "The Plutonium launcher manifest could not be fetched, auto-updating might not be possible.\n" + error.message); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | 	if (fs.existsSync(configFilePath)) { | ||||||
|  | 		readConfig(configFilePath).then(function (data) { | ||||||
|  | 			config = data; | ||||||
|  |  | ||||||
|  | 			if (config["user-info"].token === "V3ryS3cr3t4uth3nt1c4t10nT0k3n") { | ||||||
|  | 				return; | ||||||
|  | 			} else { | ||||||
|  | 				validatePlutoniumLogin(config["user-info"].token).then(function (data) { | ||||||
|  | 					if (!data.successful) { | ||||||
|  | 						config["user-info"].token = "V3ryS3cr3t4uth3nt1c4t10nT0k3n"; | ||||||
|  | 						return writeConfig(configFilePath, config).catch(function (error) { | ||||||
|  | 							console.error(error); | ||||||
|  | 						}); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					mainWindow.loadFile(path.join(__dirname, "src", "views", "games.html")); | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 		}).catch(function (error) { | ||||||
|  | 			electron.dialog.showErrorBox("Error", "Configuration file could not be read.\n" + error.message); | ||||||
|  | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		writeConfig(configFilePath, config).catch(function (error) { | ||||||
|  | 			electron.dialog.showErrorBox("Error", "Configuration file doesn't exist and could not be created.\n" + error.message); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
| }); | }); | ||||||
|  |  | ||||||
| electron.app.on("window-all-closed", function () { | electron.app.on("window-all-closed", function () { | ||||||
| @@ -252,6 +374,10 @@ electron.ipcMain.handle("login", function (event, username, password) { | |||||||
| 					}); | 					}); | ||||||
|  |  | ||||||
| 					userInfo = data; | 					userInfo = data; | ||||||
|  | 					config["user-info"] = userInfo; | ||||||
|  | 					writeConfig(configFilePath, config).catch(function (error) { | ||||||
|  | 						console.error(error); | ||||||
|  | 					}); | ||||||
|  |  | ||||||
| 					mainWindow.loadFile(path.join(__dirname, "src", "views", "games.html")); | 					mainWindow.loadFile(path.join(__dirname, "src", "views", "games.html")); | ||||||
| 				} catch (error) { | 				} catch (error) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user