aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Gwynn <[email protected]>2021-02-19 08:46:20 -0500
committerChristopher Gwynn <[email protected]>2021-02-19 08:46:20 -0500
commit7a50eeeb3353f7b6cb384611e6c1f5a1a9b4c64c (patch)
treed835438a2b4b9d8a8be88a70dfab853c8475ab49
parentauto reconnect (diff)
downloadwizard101-rpc-7a50eeeb3353f7b6cb384611e6c1f5a1a9b4c64c.tar.xz
wizard101-rpc-7a50eeeb3353f7b6cb384611e6c1f5a1a9b4c64c.zip
commands to change settings
-rw-r--r--index.js178
-rw-r--r--settings.json5
-rw-r--r--start.bat2
3 files changed, 127 insertions, 58 deletions
diff --git a/index.js b/index.js
index 9af8e0e..9b85ae3 100644
--- a/index.js
+++ b/index.js
@@ -1,97 +1,169 @@
const fs = require("fs");
const path = require("path");
+const readline = require("readline");
+const { exec } = require("child_process");
const readLastLines = require("read-last-lines");
const DiscordRPC = require("discord-rpc");
-const logPath = "C:\\ProgramData\\KingsIsle Entertainment\\Wizard101\\Bin\\WizardClient.log";
const zones = require(path.join(__dirname, "./zones.json"));
+const settings = require(path.join(__dirname, "./settings.json"));
+const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+ terminal: false
+});
let rpc;
console.log(" _ _ __ ___ __ \n (_) | /_ |/ _ \\/_ | \n __ ___ ______ _ _ __ __| || | | | || |______ _ __ _ __ ___ \n \\ \\ /\\ / / |_ / _` | \'__/ _` || | | | || |______| \'__| \'_ \\ / __|\n \\ V V /| |/ / (_| | | | (_| || | |_| || | | | | |_) | (__ \n \\_/\\_/ |_/___\\__,_|_| \\__,_||_|\\___/ |_| |_| | .__/ \\___|\n | | \n ");
-let oldLineCount, zone, world, health, activity, currentTime;
-(async () => { oldLineCount = await countLines(); })();
+function setPresence() {
+ let oldLineCount, zone, world, health, activity, currentTime;
+ (async () => { oldLineCount = await countLines(); })();
-fs.watchFile(logPath, { interval: 100 }, async (_curr, _prev) => {
- let currentLineCount = await countLines();
- readLastLines.read(logPath, currentLineCount - oldLineCount).then(async (logChunk) => {
+ fs.watchFile(settings.path, { interval: 100 }, async (_curr, _prev) => {
+ let currentLineCount = await countLines();
+ readLastLines.read(settings.path, currentLineCount - oldLineCount).then(async (logChunk) => {
// Get zone
- const zoneRegex = new RegExp(/zone = (.+),|CHARACTER LIST/gm);
- let tempZone = logChunk.match(zoneRegex);
+ const zoneRegex = new RegExp(/zone = (.+),|CHARACTER LIST/gm);
+ let tempZone = logChunk.match(zoneRegex);
- if(tempZone) {
- tempZone = zoneRegex.exec(tempZone[tempZone.length - 1]);
- zone = tempZone[1] || tempZone[0];
+ if(tempZone) {
+ tempZone = zoneRegex.exec(tempZone[tempZone.length - 1]);
+ zone = tempZone[1] || tempZone[0];
- world = /= (.+?)\/(.+)/.exec(tempZone);
- world = world && zones.zoneNames[world[1]] ? world[1] : "WizardCity";
- }
+ world = /= (.+?)\/(.+)/.exec(tempZone);
+ world = world && zones.zoneNames[world[1]] ? world[1] : "WizardCity";
+ }
- // Get health
- const healthRegex = new RegExp(/WizClientGameEf (.+): Updating health globe \(new health: (\d+), new health max: (\d+)\)/gm);
- let tempHealth = logChunk.match(healthRegex);
+ // Get health
+ const healthRegex = new RegExp(/WizClientGameEf (.+): Updating health globe \(new health: (\d+), new health max: (\d+)\)/gm);
+ let tempHealth = logChunk.match(healthRegex);
- if(tempHealth) {
- health = healthRegex.exec(tempHealth[tempHealth.length - 1]);
- health = health[3] < health[2] ? [health[2], health[2]] : [health[2], health[3]];
- }
+ if(tempHealth) {
+ health = healthRegex.exec(tempHealth[tempHealth.length - 1]);
+ health = health[3] < health[2] ? [health[2], health[2]] : [health[2], health[3]];
+ }
+
+ // Check if the game has been quit
+ if(logChunk.match(/GameClient::HandleQuit\(\)|Logout due to Away From Keyboard/) && activity) {
+ rpc.destroy();
+ process.exit();
+ }
+ }).catch((err) => { console.log(err); });
+ oldLineCount = currentLineCount;
- // Check if the game has been quit
- if(logChunk.match(/GameClient::HandleQuit\(\)|Logout due to Away From Keyboard/)) {
- rpc.destroy();
- process.exit();
+ if((!activity && zone) || activity && (activity.details !== zones[zone] || health && activity.state !== `Health: ${health[0]}/${health[1]}`)) {
+ if(!activity || activity.details !== zones[zone]) currentTime = new Date();
+ if(zone === "CHARACTER LIST") health = null;
+ activity = {
+ details: zones[zone],
+ state: zone === "CHARACTER LIST" ? undefined : `Health: ${health ? `${health[0]}/${health[1]}` : "unknown"}`,
+ startTimestamp: currentTime,
+ largeImageKey: world.toLowerCase(),
+ largeImageText: zones.zoneNames[world],
+ instance: false
+ };
+ rpc.setActivity(activity);
}
- }).catch((err) => { console.log(err); });
- oldLineCount = currentLineCount;
-
- if((!activity && zone) || activity && (activity.details !== zones[zone] || health && activity.state !== `Health: ${health[0]}/${health[1]}`)) {
- if(!activity || activity.details !== zones[zone]) currentTime = new Date();
- if(zone === "CHARACTER LIST") health = null;
- activity = {
- details: zones[zone],
- state: zone === "CHARACTER LIST" ? undefined : `Health: ${health ? `${health[0]}/${health[1]}` : "unkown"}`,
- startTimestamp: currentTime,
- largeImageKey: world.toLowerCase(),
- largeImageText: zones.zoneNames[world],
- instance: false
- };
- rpc.setActivity(activity);
- }
-});
+ });
+}
function countLines() {
return new Promise((resolve, reject) => {
let lineCount = 0;
- fs.createReadStream(logPath).on("data", (buffer) => {
+ fs.createReadStream(settings.path).on("data", (buffer) => {
let index = -1;
lineCount--;
do {
index = buffer.indexOf(10, index + 1);
lineCount++;
} while(index !== -1);
- }).on("end", () => {
- resolve(lineCount);
- }).on("error", reject);
+ }).on("end", () => resolve(lineCount)).on("error", reject);
});
}
+(async function configureSettings() {
+ const defaultPath = "C:\\ProgramData\\KingsIsle Entertainment\\Wizard101\\Bin\\WizardClient.log";
+ const defaultSteamPath = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Wizard101\\Bin\\WizardClient.log";
+
+ if(!settings.path || !fs.existsSync(settings.path)) {
+ settings.path === null;
+ const defaultValidPath = fs.existsSync(defaultPath) ? defaultPath : fs.existsSync(defaultSteamPath) ? defaultSteamPath : null;
+ if(defaultValidPath) {
+ settings.path = defaultValidPath;
+ await fs.writeFile(path.join(__dirname, "./settings.json"), JSON.stringify(settings), () => { /* do nothing */ });
+ console.log(`Fetching data for RPC from ${defaultValidPath.slice(0, defaultValidPath.length - 21)}\n`);
+ }
+ }
+
+ // handle command inputs
+ if(!settings.startup) {
+ console.log("No startup settings detected, using the 'quick' startup setting!\nIn the future when you want to play Wizard101 and have Discord RPC working, run this program instead and Wizard101-rpc will quick launch Wizard101 for you.\n\nYou can change this by using the 'startup' command.\nUsage: startup <quick|normal|none>\nExample Usage:\nstartup quick - Set wizard101-rpc to quick launch (skip patching, instant login) Wizard101 on startup.\nstartup normal - Set wizard101-rpc to launch Wizard101 normally on startup.\nstartup none - Set wizard101-rpc to not launch Wizard101 on startup.\n");
+ settings.startup = "quick";
+ await fs.writeFile(path.join(__dirname, "./settings.json"), JSON.stringify(settings), () => { /* do nothing */ });
+ }
+ if(!settings.path) console.log("Could not find Wizard101 at a default path! Please enter a valid path to continue.\nExample path (does not have to be steam): D:\\Steam\\steamapps\\common\\Wizard101");
+
+ rl.on("line", async (input) => {
+ if(!settings.path) await pathCommand(null, input);
+ if(!rpc && settings.path) return connectDiscord();
+
+ let args = input.split(/\s+/g);
+ if(!args[0] || typeof args[0] !== "string") return;
+ args[0] = args[0].toLowerCase();
+ if(args[0] === "path") pathCommand(args);
+ if(args[0] === "startup") startupCommand(args);
+ });
+
+ async function pathCommand(args, init) {
+ if(args && !args[1]) return console.log("\nSets a path to the Wizard101 folder of the client that wizard101-rpc will report from.\nUsage: path <path>\nExample Usage: path D:\\Steam\\steamapps\\common\\Wizard101");
+ if(!fs.existsSync(`${init || args[1]}\\Bin\\WizardClient.log`)) return console.log(init ? `\nCould not find Wizard101 at the path "${init || args[1]}".\nA valid path will need to be supplied to the Wizard101 folder before wizard101-rpc can run properly. Make sure you've ran the game at least once. Please try again.\nExample path (does not have to be steam): D:\\Steam\\steamapps\\common\\Wizard101` : `\nCould not find Wizard101 at the path "${init || args[1]}".\nUsage: path <path>\nExample usage: path D:\\Steam\\steamapps\\common\\Wizard101`);
+
+ settings.path = `${init || args[1]}\\Bin\\WizardClient.log`;
+ await fs.writeFile(path.join(__dirname, "./settings.json"), JSON.stringify(settings), () => { /* do nothing */ });
+ console.log(`\nNew path set to "${init || args[1]}". If a path was already set, wizard101-rpc won't read from the new path until restarted.`);
+ }
+
+ async function startupCommand(args) {
+ if(!args[1]) return console.log("\nSets how wizard101-rpc will start Wizard101, if at all.\nUsage: startup <quick|normal|none>\n\nExample Usage:\nstartup quick - Set wizard101-rpc to quick launch Wizard101 on startup.\nstartup normal - Set wizard101-rpc to launch Wizard101 normally on startup.\nstartup none - Set wizard101-rpc to not launch Wizard101 on startup.");
+ args[1] = args[1].toLowerCase();
+
+ if(args[1] === "quick" || args[1] === "normal" || args[1] === "none") {
+ settings.startup = args[1];
+ await fs.writeFile(path.join(__dirname, "./settings.json"), JSON.stringify(settings), () => { /* do nothing */ });
+ console.log(`\nStartup settings set to '${args[1]}'.`);
+ } else {
+ console.log(`\nInvalid argument '${args[1]}'. Please use 'quick', 'normal', or 'none'.`);
+ }
+ }
+ if(settings.path) connectDiscord();
+}());
+
let reconnect;
-const connectDiscord = () => {
- console.log("Connecting to your Discord app...");
+function connectDiscord() {
+ console.log("\nConnecting to your Discord app...");
+ rl.pause();
rpc = new DiscordRPC.Client({ transport: "ipc" });
rpc.once("ready", () => {
- console.log("Successfully connected to Discord!");
+ console.log("Successfully connected to Discord!\nWizard101-rpc is ready! Information will be shown on your Discord profile on game startup or the next zone change.");
+ clearInterval(reconnect);
+ rl.resume();
+ setPresence();
+
+ // Launch wiz
+ if(settings.startup === "none") return;
+ process.chdir(settings.path.slice(0, settings.path.length - (settings.startup === "quick" ? 17 : 21)));
+ settings.startup === "quick" ? exec("WizardGraphicalClient.exe -L 165.193.63.4 12000", (err) => console.log(`\nQuick launched Wizard101!\nIf you encounter an error in-game, try running Wizard101 normally.\n${err ? err : ""}`)) : settings.startup === "normal" ? exec("Wizard101.exe", _err /* an error will always be made, even when successful*/ => console.log("\nLaunched Wizard101!")) : null;
});
rpc.login({ clientId: "799404226081849345" }).then(() => {
clearInterval(reconnect);
}).catch((err) => {
- console.log(`${err}\nMake sure Discord is running. You probably need to restart Discord (Ctrl+R on Discord).\n`);
- if(!reconnect) {
+ console.log(`${err}\nMake sure Discord is running. You might need to restart Discord (Ctrl+R on Discord).`);
+ if(!reconnect && !rpc.user) {
reconnect = setInterval(connectDiscord, 10050);
connectDiscord();
}
});
-};
-connectDiscord();
+}
diff --git a/settings.json b/settings.json
index d6998d5..2353159 100644
--- a/settings.json
+++ b/settings.json
@@ -1,4 +1 @@
-{
- "path": "",
- "startup": ""
-} \ No newline at end of file
+{"path":"","startup":""} \ No newline at end of file
diff --git a/start.bat b/start.bat
index a77d084..4ccb668 100644
--- a/start.bat
+++ b/start.bat
@@ -1 +1 @@
-nodemon index.js \ No newline at end of file
+nodemon index.js --ignore *.json \ No newline at end of file