From d71157e6c58724f232494bd7e788c13025b4b9ba Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Tue, 17 Nov 2020 00:49:08 -0800
Subject: [PATCH] Support 3rd party installer files for external programs
 (doors)

By simply installing a supported 3rd party door game into your
"xtrn" directory, install-xtrn.js or xtrn-setup.js can automatically
discover and configure your newly installed door for Synchronet. Easy peasy.

Resolves issue #181 (great idea) by Michael Long. Deuce and others have had
similar ideas in the past.

Now, we don't have to rely on the authors of potentially-abandoned door games
to create and include a Synchronet install-xtrn.ini file. We can just do that
for ourselves and make installing all (known) door games super easy.

Many more xtrn/3rdp-install/*.ini files will be forthcoming!
---
 exec/install-xtrn.js           |  8 ++++
 exec/load/install-3rdp-xtrn.js | 81 ++++++++++++++++++++++++++++++++++
 exec/xtrn-setup.js             |  9 ++++
 xtrn/3rdp-install/doormud.ini  | 15 +++++++
 4 files changed, 113 insertions(+)
 create mode 100755 exec/load/install-3rdp-xtrn.js
 create mode 100644 xtrn/3rdp-install/doormud.ini

diff --git a/exec/install-xtrn.js b/exec/install-xtrn.js
index 729b0b6a17..ded2392bca 100644
--- a/exec/install-xtrn.js
+++ b/exec/install-xtrn.js
@@ -443,6 +443,14 @@ for (var i = 0; i < argc; i++) {
 		ini_list.push(argv[i]);
 }
 
+if(!ini_list.length) {
+	var lib = load({}, "install-3rdp-xtrn.js");
+	var out = lib.scan(options);
+	for (var i in out) {
+		print(out[i]);
+	}
+}
+
 function find_startup_dir(dir)
 {
 	for (var i in xtrn_area.prog) {
diff --git a/exec/load/install-3rdp-xtrn.js b/exec/load/install-3rdp-xtrn.js
new file mode 100755
index 0000000000..8988f7066f
--- /dev/null
+++ b/exec/load/install-3rdp-xtrn.js
@@ -0,0 +1,81 @@
+// install-3rdp-xtrn.js
+
+// Looks for matching (name and MD5-sum) executables in xtrn/*.
+// If one is found, the corresponding .ini file is copied to that xtrn/*
+// (startup) directory with the name install-xtrn.ini so it'll be picked up by
+// install-xtrn.js and xtrn-setup.js.
+// Multiple md5 values can be specified, separated by commas, for multiple
+// supported versions of the same door.
+
+// The additional install-xtrn.ini keys are:
+// exe = filename of door's executable
+// md5 = comma-separated list of md5-sums (in lowercase hexadecimal)
+
+"use strict";
+
+function scan(options)
+{
+	if(options === undefined)
+		options = {};
+	if(!options.src_dir)
+		options.src_dir = "../xtrn/3rdp-install/";
+	if(!options.xtrn_dir)
+		options.xtrn_dir = "../xtrn/";
+	
+	var out = [];
+	var exe_list = {};
+	
+	directory(options.src_dir + '*.ini').forEach(function (e) {
+		const f = new File(e);
+		if (!f.open('r')) {
+			out.push("!Error " + f.error + " opening " + f.name);
+			return;
+		}
+		const ini = f.iniGetObject(/* lowercase: */true);
+		f.close();
+		if (!ini.exe) {
+			out.push("!No executable filename specified in " + f.name);
+			return;
+		}
+		if (!ini.md5) {
+			out.push("!No md5 list specified in " + f.name);
+			return;
+		}
+		if (!exe_list[ini.exe])
+			exe_list[ini.exe] = {};
+		var md5_list = ini.md5.split(',');
+		for(var i in md5_list)
+			exe_list[ini.exe][md5_list[i]] = f.name;
+	});
+	
+	for(var i in exe_list) {
+		directory(options.xtrn_dir + '*').forEach(function (e) {
+			const f = new File(e + i);
+			if (!f.open('rb')) {
+				return;
+			}
+			var md5 = f.md5_hex;
+			f.close();
+			if(!exe_list[i][md5]) {
+				if(options.debug)
+					out.push("!MD5 sum of " + f.name + " (" + md5 + ") not found.");
+				return;
+			}
+			var startup_dir = f.name.substr(0, Math.max(f.name.lastIndexOf("/"), f.name.lastIndexOf("\\"), 0));
+			var ini_fname = startup_dir + "/install-xtrn.ini";
+			if (file_exists(ini_fname) && !options.overwrite) {
+				if(options.debug)
+					out.push(ini_fname + " already exists");
+				return;
+			}
+			if (!file_copy(exe_list[i][md5], ini_fname)) {
+				out.push("!Error copying " + exe_list[i][md5] + " to " + ini_fname);
+				return;
+			}
+			out.push(exe_list[i][md5] + " copied to " + ini_fname);
+		});
+	}
+	return out;
+}
+
+this;
\ No newline at end of file
diff --git a/exec/xtrn-setup.js b/exec/xtrn-setup.js
index f8f04006ce..45b99a1f82 100644
--- a/exec/xtrn-setup.js
+++ b/exec/xtrn-setup.js
@@ -1,6 +1,15 @@
 // $Id: xtrn-setup.js,v 1.10 2020/05/09 03:37:35 echicken Exp $
 // vi: tabstop=4
 
+// Locate/copy 3rd party door installer files
+{
+	var lib = load({}, 'install-3rdp-xtrn.js');
+	var out = lib.scan();
+	for(var i in out) {
+		alert(out[i]);
+	}
+}
+
 load('sbbsdefs.js');
 load('frame.js');
 load('tree.js');
diff --git a/xtrn/3rdp-install/doormud.ini b/xtrn/3rdp-install/doormud.ini
new file mode 100644
index 0000000000..b21ad50d4c
--- /dev/null
+++ b/xtrn/3rdp-install/doormud.ini
@@ -0,0 +1,15 @@
+; Install instructions for DoorMUD v0.99
+Name: DoorMUD: Land of the Forgotten
+Desc: Massive text-based role-playing game for Windows
+By:   RhythmNp (Evan Elias)
+Cats: Games
+Subs: Multiplayer, Adventure, MUD, Native
+exe:  dmud32.exe
+md5:  b92fe52e1883ad8502cb2ea9de75173f
+
+[prog:DOORMUD]
+cmd  = dmud32
+ars = WIN32
+execution_ars  = NOT GUEST
+settings = XTRN_MULTIUSER | XTRN_NATIVE
+type = XTRN_SBBS
-- 
GitLab