diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-disk/sync.js b/zefie_wtvp_minisrv/ServiceVault/wtv-disk/sync.js index 52bd0ceb..6f1c0b46 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-disk/sync.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-disk/sync.js @@ -1,5 +1,5 @@ const WTVDownloadList = require("./WTVDownloadList.js"); -var wtvdl = new WTVDownloadList(service_name); +var wtvdl = new WTVDownloadList(minisrv_config, service_name); var force_update = (request_headers.query.force == "true") ? true : false; if (request_headers['wtv-request-type'] == 'download') { @@ -272,5 +272,5 @@ if (request_headers['wtv-request-type'] == 'download') { var message = request_headers.query.message || "Retrieving files..."; var main_message = request_headers.query.main_message || "Your receiver is downloading files."; headers = "200 OK\nContent-Type: text/html"; - data = wtvdl.getSyncPage(minisrv_config, message, request_headers.query.group, request_headers.query.diskmap, main_message, message, force_update) + data = wtvdl.getSyncPage(message, request_headers.query.group, request_headers.query.diskmap, main_message, message, force_update) } \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-disk/uptest.js b/zefie_wtvp_minisrv/ServiceVault/wtv-disk/uptest.js new file mode 100644 index 00000000..b015f7a8 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-disk/uptest.js @@ -0,0 +1,57 @@ +const WTVDownloadList = require("./WTVDownloadList.js"); +var wtvdl = new WTVDownloadList(minisrv_config); +if (request_headers['wtv-request-type'] == 'download') { + console.log(request_headers.post_data.toString(CryptoJS.enc.Latin1)); + wtvdl.reset(); + var froot = "file://disk/Demo/"; + var fget = [ + "attract.mpg", + "can-you-hear.mpg", + "explore.mpg", + "hear.html", + "index.html", + "menu1.html", + "menu2.html", + "menu3.html", + "menu4.html", + "service.html", + "splash-mits.mpg", + "splash-phil.mpg", + "splash-sony.mpg", + "splash1.html", + "splash2.html", + "splash3.html", + "what-is-it.html", + "what-is-it.mpg", + "what-others.html", + "what-others.mpg", + "whats-in-it.html", + "whats-in-it.mpg", + "whats-in-it.mpg.old" + ]; + + Object.keys(fget).forEach(function (k) { + wtvdl.putUserStore(froot + fget[k]); + }); + headers = "200 OK\nContent-type: " + wtvdl.content_type; + data = wtvdl.getDownloadList(); + console.log(data); +} else { + headers = "200 OK\nContent-type: text/html"; + var success_url = new clientShowAlert({ + 'image': minisrv_config.config.service_logo, + 'message': "Upload successful!", + 'buttonlabel1': "Okay", + 'buttonaction1': "client:goback", + 'noback': true, + }).getURL(); + + var fail_url = new clientShowAlert({ + 'image': minisrv_config.config.service_logo, + 'message': "Upload failed...", + 'buttonlabel1': "Okay...", + 'buttonaction1': "client:goback", + 'noback': true, + }).getURL(); + data = wtvdl.getSyncPage("Testing", "UploadTest", null, "Your receiver is uploading files.", "Sending files", null, success_url, fail_url, "wtv-disk:/uptest"); +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-disk/userbrowser.js b/zefie_wtvp_minisrv/ServiceVault/wtv-disk/userbrowser.js new file mode 100644 index 00000000..72804117 --- /dev/null +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-disk/userbrowser.js @@ -0,0 +1,23 @@ +// todo some fancy ass file manager or something + + +if (socket.ssid) { + if (ssid_sessions[socket.ssid]) { + if (ssid_sessions[socket.ssid].isRegistered()) { + data = ssid_sessions[socket.ssid].getUserStoreFileByURL("file://Disk/Demo/allyouneed.html"); + //data = ssid_sessions[socket.ssid].getUserStoreFile("Disk/Demo/allyouneed.html"); + var contype = ssid_sessions[socket.ssid].getUserStoreContentType("file://Disk/Demo/allyouneed.html"); + + if (data) { + headers = "200 OK\n"; + headers += "Content-Type: " + contype; + } + } + } +} + +if (!headers) { + var errpage = doErrorPage(400) + headers = errpage[0]; + data = errpage[1]; +} \ No newline at end of file diff --git a/zefie_wtvp_minisrv/ServiceVault/wtv-home/home.js b/zefie_wtvp_minisrv/ServiceVault/wtv-home/home.js index 414b42c8..6b804319 100644 --- a/zefie_wtvp_minisrv/ServiceVault/wtv-home/home.js +++ b/zefie_wtvp_minisrv/ServiceVault/wtv-home/home.js @@ -7,7 +7,7 @@ Content-type: text/html` if (request_headers.query.url) headers += "\nwtv-visit: " + request_headers.query.url; var cryptstatus = ((socket_sessions[socket.id].secure === true) ? "Encrypted" : "Not Encrypted") -var comp_type = shouldWeCompress(socket.ssid,'text/html'); +var comp_type = wtvmime.shouldWeCompress(ssid_sessions[socket.ssid],'text/html'); var compstatus = "uncompressed"; switch (comp_type) { case 1: diff --git a/zefie_wtvp_minisrv/WTVClientSessionData.js b/zefie_wtvp_minisrv/WTVClientSessionData.js index 912f631e..48adda55 100644 --- a/zefie_wtvp_minisrv/WTVClientSessionData.js +++ b/zefie_wtvp_minisrv/WTVClientSessionData.js @@ -11,20 +11,19 @@ class WTVClientSessionData { login_security = null; capabilities = null; session_storage = ""; - hide_ssid_in_logs = true; + minisrv_config = []; wtvshared = null; wtvmime = null; - constructor(ssid, hide_ssid_in_logs, session_storage_directory) { - var { WTVShared, clientShowAlert } = require('./WTVShared.js'); - var WTVMimeTypes = require('./WTVMimeTypes.js'); - this.wtvshared = new WTVShared(); - this.wtvmime = new WTVMimeTypes(); + constructor(minisrv_config, ssid) { + if (!minisrv_config) throw ("minisrv_config required"); + var WTVShared = require('./WTVShared.js')['WTVShared']; + var WTVMime = require('./WTVMime.js'); + this.minisrv_config = minisrv_config; + this.wtvshared = new WTVShared(minisrv_config); + this.wtvmime = new WTVMime(minisrv_config); this.ssid = ssid; - if (hide_ssid_in_logs) this.hide_ssid_in_logs = hide_ssid_in_logs; - if (!session_storage_directory) session_storage_directory = __dirname + this.path.sep + "SessionStore"; - this.session_storage = session_storage_directory; this.data_store = new Array(); this.session_store = {}; } @@ -35,7 +34,7 @@ class WTVClientSessionData { */ getUserStoreDirectory() { if (!this.isRegistered()) return false; - return this.session_storage + this.path.sep + this.ssid + this.path.sep; + return this.minisrv_config.config.SessionStore + this.path.sep + this.ssid + this.path.sep; } /** @@ -238,8 +237,8 @@ class WTVClientSessionData { loadSessionData(raw_data = false) { try { - if (this.fs.lstatSync(this.session_storage + this.path.sep + this.ssid + ".json")) { - var json_data = this.fs.readFileSync(this.session_storage + this.path.sep + this.ssid + ".json", 'Utf8') + if (this.fs.lstatSync(this.minisrv_config.config.SessionStore + this.path.sep + this.ssid + ".json")) { + var json_data = this.fs.readFileSync(this.minisrv_config.config.SessionStore + this.path.sep + this.ssid + ".json", 'Utf8') if (raw_data) return json_data; var session_data = JSON.parse(json_data); @@ -270,7 +269,7 @@ class WTVClientSessionData { // only save if file has changed var json_save_data = JSON.stringify(this.session_store); var json_load_data = this.loadSessionData(true); - if (json_save_data != json_load_data) this.fs.writeFileSync(this.session_storage + this.path.sep + this.ssid + ".json", JSON.stringify(this.session_store), "Utf8"); + if (json_save_data != json_load_data) this.fs.writeFileSync(this.minisrv_config.config.SessionStore + this.path.sep + this.ssid + ".json", JSON.stringify(this.session_store), "Utf8"); return true; } catch (e) { console.error(" # Error saving session data for", this.wtvshared.filterSSID(this.ssid), e); @@ -296,7 +295,7 @@ class WTVClientSessionData { isRegistered() { var self = this; var ssid_match = false; - this.fs.readdirSync(this.session_storage).forEach(file => { + this.fs.readdirSync(this.minisrv_config.config.SessionStore).forEach(file => { if (!file.match(/.*\.json/ig)) return; if (ssid_match) return; if (file.split('.')[0] == self.ssid) ssid_match = true; @@ -306,8 +305,8 @@ class WTVClientSessionData { unregisterBox() { try { - if (this.fs.lstatSync(this.session_storage + this.path.sep + this.ssid + ".json")) { - this.fs.unlinkSync(this.session_storage + this.path.sep + this.ssid + ".json"); + if (this.fs.lstatSync(this.minisrv_config.config.SessionStore + this.path.sep + this.ssid + ".json")) { + this.fs.unlinkSync(this.minisrv_config.config.SessionStore + this.path.sep + this.ssid + ".json"); this.session_store = {}; return true; } diff --git a/zefie_wtvp_minisrv/WTVDownloadList.js b/zefie_wtvp_minisrv/WTVDownloadList.js index 78ffa567..5e3c60f1 100644 --- a/zefie_wtvp_minisrv/WTVDownloadList.js +++ b/zefie_wtvp_minisrv/WTVDownloadList.js @@ -9,14 +9,16 @@ class WTVDownloadList { content_type = "wtv/download-list"; wtvshared = null; clientShowAlert = null; + minisrv_config = []; /** * Constructs the WTVDownloadList Class * @param {string} service_name Service name to use in wtv-urls */ - constructor(service_name = "wtv-disk") { + constructor(minisrv_config, service_name = "wtv-disk") { var { WTVShared, clientShowAlert } = require('./WTVShared.js'); - this.wtvshared = new WTVShared(); + this.minisrv_config = minisrv_config; + this.wtvshared = new WTVShared(minisrv_config); this.clientShowAlert = clientShowAlert; this.service_name = service_name this.clear(); @@ -214,7 +216,7 @@ class WTVDownloadList { * @param {string|null} url Use your own URL for client:fetch?source= instead of our generated one * @returns {string} HTML Download Page */ - getSyncPage(minisrv_config, title, group, diskmap = null, main_message = null, message = null, force_update = null, success_url = null, fail_url = null, url = null) { + getSyncPage(title, group, diskmap = null, main_message = null, message = null, force_update = null, success_url = null, fail_url = null, url = null) { // Begin Set defaults if (main_message === null) main_message = "Your receiver is downloading files."; @@ -225,7 +227,7 @@ class WTVDownloadList { if (url === null) url = this.service_name + ":/sync?diskmap=" + escape(diskmap) + "&force=" + force_update; if (success_url === null) success_url = new this.clientShowAlert({ - 'image': minisrv_config.config.service_logo, + 'image': this.minisrv_config.config.service_logo, 'message': "Download successful!", 'buttonlabel1': "Okay", 'buttonaction1': "client:goback", @@ -233,7 +235,7 @@ class WTVDownloadList { }).getURL(); if (fail_url === null) fail_url = new this.clientShowAlert({ - 'image': minisrv_config.config.service_logo, + 'image': this.minisrv_config.config.service_logo, 'message': "Download failed...", 'buttonlabel1': "Okay...", 'buttonaction1': "client:goback", @@ -253,7 +255,7 @@ class WTVDownloadList {
- + diff --git a/zefie_wtvp_minisrv/WTVMimeTypes.js b/zefie_wtvp_minisrv/WTVMime.js similarity index 50% rename from zefie_wtvp_minisrv/WTVMimeTypes.js rename to zefie_wtvp_minisrv/WTVMime.js index a0024c01..ffaa9544 100644 --- a/zefie_wtvp_minisrv/WTVMimeTypes.js +++ b/zefie_wtvp_minisrv/WTVMime.js @@ -3,15 +3,17 @@ */ -class WTVMimeTypes { +class WTVMime { mime = require('mime-types'); wtvshared = null; + minisrv_config = []; - constructor() { - var { WTVShared, clientShowAlert } = require('./WTVShared.js'); - this.wtvshared = new WTVShared(); + constructor(minisrv_config) { + var WTVShared = require('./WTVShared.js')['WTVShared']; + this.minisrv_config = minisrv_config; + this.wtvshared = new WTVShared(minisrv_config); if (!String.prototype.reverse) { String.prototype.reverse = function () { var splitString = this.split(""); @@ -22,6 +24,68 @@ class WTVMimeTypes { } } + + shouldWeCompress(ssid_session, headers_obj) { + var compress_data = false; + var compression_type = 0; // no compression + if (ssid_session) { + if (ssid_session.capabilities) { + if (ssid_session.capabilities['client-can-receive-compressed-data']) { + + if (this.minisrv_config.config.enable_lzpf_compression || this.minisrv_config.config.force_compression_type) { + compression_type = 1; // lzpf + } + + if (ssid_session) { + // if gzip is enabled... + if (this.minisrv_config.config.enable_gzip_compression || this.minisrv_config.config.force_compression_type) { + var is_bf0app = ssid_session.get("wtv-client-rom-type") == "bf0app"; + var is_minibrowser = (ssid_session.get("wtv-needs-upgrade") || ssid_session.get("wtv-used-8675309")); + var is_softmodem = ssid_session.get("wtv-client-rom-type").match(/softmodem/); + if (!is_bf0app && ((!is_softmodem && !is_minibrowser) || (is_softmodem && !is_minibrowser))) { + // softmodem boxes do not appear to support gzip in the minibrowser + // LC2 appears to support gzip even in the MiniBrowser + // LC2 and newer approms appear to support gzip + // bf0app does not appear to support gzip + compression_type = 2; // gzip + } + } + } + + + + // mostly for debugging + if (this.minisrv_config.config.force_compression_type == "lzpf") compression_type = 1; + if (this.minisrv_config.config.force_compression_type == "gzip") compression_type = 2; + + // do not compress if already encoded + if (headers_obj["Content-Encoding"]) return 0; + + // should we bother to compress? + var content_type = ""; + if (typeof (headers_obj) == 'string') content_type = headers_obj; + else content_type = (typeof (headers_obj["wtv-modern-content-type"]) != 'undefined') ? headers_obj["wtv-modern-content-type"] : headers_obj["Content-Type"]; + + if (content_type) { + // both lzpf and gzip + if (content_type.match(/^text\//) && content_type != "text/tellyscript") compress_data = true; + else if (content_type.match(/^application\/(x-?)javascript$/)) compress_data = true; + else if (content_type == "application/json") compress_data = true; + if (compression_type == 2) { + // gzip only + if (content_type.match(/^audio\/(x-)?[s3m|mod|xm]$/)) compress_data = true; // s3m, mod, xm + if (content_type.match(/^audio\/(x-)?[midi|wav|wave]$/)) compress_data = true; // midi & wav + if (content_type.match(/^binary\/x-wtv-approm$/)) compress_data = true; // approms + } + } + } + } + } + + // return compression_type if compress_data = true + return (compress_data) ? compression_type : 0; + } + /** * Gets the WebTV Content-Type * @param {string} path Path to a file @@ -130,4 +194,4 @@ class WTVMimeTypes { } -module.exports = WTVMimeTypes; +module.exports = WTVMime; diff --git a/zefie_wtvp_minisrv/WTVShared.js b/zefie_wtvp_minisrv/WTVShared.js index 5da2faff..eb744aff 100644 --- a/zefie_wtvp_minisrv/WTVShared.js +++ b/zefie_wtvp_minisrv/WTVShared.js @@ -5,8 +5,10 @@ class WTVShared { path = require('path'); + minisrv_config = []; - constructor() { + constructor(minisrv_config) { + this.minisrv_config = minisrv_config; if (!String.prototype.reverse) { String.prototype.reverse = function () { var splitString = this.split(""); @@ -22,7 +24,7 @@ class WTVShared { * @param {string|Array} obj SSID String or Headers Object */ filterSSID(obj) { - if (this.hide_ssid_in_logs === true) { + if (this.minisrv_config.config.hide_ssid_in_logs === true) { if (typeof (obj) == "string") { if (obj.substr(0, 8) == "MSTVSIMU") { return obj.substr(0, 10) + ('*').repeat(10) + obj.substr(20); diff --git a/zefie_wtvp_minisrv/app.js b/zefie_wtvp_minisrv/app.js index 17a2600c..fa4463a7 100644 --- a/zefie_wtvp_minisrv/app.js +++ b/zefie_wtvp_minisrv/app.js @@ -14,12 +14,9 @@ var WTVSec = require('./WTVSec.js'); var WTVLzpf = require('./WTVLzpf.js'); var WTVClientCapabilities = require('./WTVClientCapabilities.js'); var WTVClientSessionData = require('./WTVClientSessionData.js'); -var WTVMimeTypes = require("./WTVMimeTypes.js"); +var WTVMime = require("./WTVMime.js"); var { WTVShared, clientShowAlert } = require("./WTVShared.js"); -const wtvshared = new WTVShared(); -const wtvmime = new WTVMimeTypes(); - process .on('SIGTERM', shutdown('SIGTERM')) .on('SIGINT', shutdown('SIGINT')) @@ -536,67 +533,6 @@ function headerStringToObj(headers, response = false) { return headers_obj; } -function shouldWeCompress(ssid, headers_obj) { - var compress_data = false; - var compression_type = 0; // no compression - if (ssid_sessions[ssid]) { - if (ssid_sessions[ssid].capabilities) { - if (ssid_sessions[ssid].capabilities['client-can-receive-compressed-data']) { - - if (minisrv_config.config.enable_lzpf_compression || minisrv_config.config.force_compression_type) { - compression_type = 1; // lzpf - } - - if (ssid_sessions[ssid]) { - // if gzip is enabled... - if (minisrv_config.config.enable_gzip_compression || minisrv_config.config.force_compression_type) { - var is_bf0app = ssid_sessions[ssid].get("wtv-client-rom-type") == "bf0app"; - var is_minibrowser = (ssid_sessions[ssid].get("wtv-needs-upgrade") || ssid_sessions[ssid].get("wtv-used-8675309")); - var is_softmodem = ssid_sessions[ssid].get("wtv-client-rom-type").match(/softmodem/); - if (!is_bf0app && ((!is_softmodem && !is_minibrowser) || (is_softmodem && !is_minibrowser))) { - // softmodem boxes do not appear to support gzip in the minibrowser - // LC2 appears to support gzip even in the MiniBrowser - // LC2 and newer approms appear to support gzip - // bf0app does not appear to support gzip - compression_type = 2; // gzip - } - } - } - - - - // mostly for debugging - if (minisrv_config.config.force_compression_type == "lzpf") compression_type = 1; - if (minisrv_config.config.force_compression_type == "gzip") compression_type = 2; - - // do not compress if already encoded - if (headers_obj["Content-Encoding"]) return 0; - - // should we bother to compress? - var content_type = ""; - if (typeof (headers_obj) == 'string') content_type = headers_obj; - else content_type = (typeof (headers_obj["wtv-modern-content-type"]) != 'undefined') ? headers_obj["wtv-modern-content-type"] : headers_obj["Content-Type"]; - - if (content_type) { - // both lzpf and gzip - if (content_type.match(/^text\//) && content_type != "text/tellyscript") compress_data = true; - else if (content_type.match(/^application\/(x-?)javascript$/)) compress_data = true; - else if (content_type == "application/json") compress_data = true; - if (compression_type == 2) { - // gzip only - if (content_type.match(/^audio\/(x-)?[s3m|mod|xm]$/)) compress_data = true; // s3m, mod, xm - if (content_type.match(/^audio\/(x-)?[midi|wav|wave]$/)) compress_data = true; // midi & wav - if (content_type.match(/^binary\/x-wtv-approm$/)) compress_data = true; // approms - } - } - } - } - } - - // return compression_type if compress_data = true - return (compress_data) ? compression_type : 0; -} - async function sendToClient(socket, headers_obj, data) { var headers = ""; var content_length = 0; @@ -634,7 +570,7 @@ async function sendToClient(socket, headers_obj, data) { // if box can do compression, see if its worth enabling // small files actually get larger, so don't compress them var compression_type = 0; - if (content_length >= 256) compression_type = shouldWeCompress(socket.ssid, headers_obj); + if (content_length >= 256) compression_type = wtvmime.shouldWeCompress(ssid_sessions[socket.ssid], headers_obj); // compress if needed if (compression_type > 0 && content_length > 0 && headers_obj['http_response'].substring(0,3) == "200") { @@ -949,7 +885,7 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq socket.ssid = wtvshared.makeSafeSSID(headers["wtv-client-serial-number"]); if (socket.ssid != null) { if (!ssid_sessions[socket.ssid]) { - ssid_sessions[socket.ssid] = new WTVClientSessionData(socket.ssid,minisrv_config.config.hide_ssid_in_logs); + ssid_sessions[socket.ssid] = new WTVClientSessionData(minisrv_config, socket.ssid); ssid_sessions[socket.ssid].SaveIfRegistered(); } if (!ssid_sessions[socket.ssid].data_store.sockets) ssid_sessions[socket.ssid].data_store.sockets = new Set(); @@ -967,7 +903,7 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq if (headers["wtv-capability-flags"] != null) { if (!ssid_sessions[socket.ssid]) { - ssid_sessions[socket.ssid] = new WTVClientSessionData(socket.ssid, minisrv_config.config.hide_ssid_in_logs); + ssid_sessions[socket.ssid] = new WTVClientSessionData(minisrv_config, socket.ssid); ssid_sessions[socket.ssid].SaveIfRegistered(); } if (!ssid_sessions[socket.ssid].capabilities) ssid_sessions[socket.ssid].capabilities = new WTVClientCapabilities(headers["wtv-capability-flags"]); @@ -1091,7 +1027,7 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq } // handle POST - if (headers['request']) { + if (headers['request'] && !socket_sessions[socket.id].expecting_post_data) { if (headers['request'].substring(0, 4) == "POST") { socket.setTimeout(minisrv_config.config.post_data_socket_timeout * 1000); if (typeof socket_sessions[socket.id].post_data == "undefined") { @@ -1120,6 +1056,15 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq } else { // expecting more data (see below) socket_sessions[socket.id].expecting_post_data = true; + if (!socket_sessions[socket.id].post_data) socket_sessions[socket.id].post_data = ''; + if (socket_sessions[socket.id].secure) { + // decrypt if encrypted + socket_sessions[socket.id].post_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, CryptoJS.enc.Hex.parse(socket_sessions[socket.id].post_data))).toString(CryptoJS.enc.Hex); + } else { + // just pass it over + socket_sessions[socket.id].post_data = socket_sessions[socket.id].post_data; + } + socket_sessions[socket.id].post_data += CryptoJS.enc.Hex.parse(socket_sessions[socket.id].post_data); console.log(" * Incoming", post_string, "request on", socket.id, "from", wtvshared.filterSSID(socket.ssid), "to", headers['request_url'], "(expecting", socket_sessions[socket.id].post_data_length, "bytes of data from client...)"); } if (socket_sessions[socket.id].post_data.length > (socket_sessions[socket.id].post_data_length * 2)) { @@ -1568,6 +1513,8 @@ bind_ports.forEach(function (v) { initstring = initstring.substring(0, initstring.length - 2); +const wtvshared = new WTVShared(minisrv_config); +const wtvmime = new WTVMime(minisrv_config); console.log(" * Started server on ports " + initstring + "...") var listening_ip_string = (minisrv_config.config.bind_ip != "0.0.0.0") ? "IP: " + minisrv_config.config.bind_ip : "all interfaces"; diff --git a/zefie_wtvp_minisrv/package.json b/zefie_wtvp_minisrv/package.json index f16d9473..53ecd2aa 100644 --- a/zefie_wtvp_minisrv/package.json +++ b/zefie_wtvp_minisrv/package.json @@ -1,6 +1,6 @@ { "name": "zefie_wtvp_minisrv", - "version": "0.9.16", + "version": "0.9.17", "description": "WebTV Service (WTVP) Emulation Server", "main": "app.js", "homepage": "https://github.com/zefie/zefie_wtvp_minisrv", diff --git a/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj b/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj index eea66531..7d786788 100644 --- a/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj +++ b/zefie_wtvp_minisrv/zefie_wtvp_minisrv.njsproj @@ -52,6 +52,15 @@ Code + + Code + + + Code + + + Code + Code @@ -283,6 +292,9 @@ Code + + Code + Code @@ -290,6 +302,9 @@ Code + + Code +