- minor update: app.js: fix found file path in log on windows
 - update: WTVClientCapabilities.js: allow setting flags to false, to prevent potential issue with changing cap flags
 - update: add 'hasCap(flag)' function to WTVClientSessionData for easier client-capabilities checking (see wtv-home/home.js for an example)
 - update: add isMiniBrowser() to WTVClientSessionData for easier detection of MiniBrowser.
 - update: add 'setIRCNick()' function to WTVClientSessionData for ease of use
 - update: add primative getMaxUsernameLength() to overcome username limitation in older builds
 - update: wtv-chat:/home template
 - update: app.js: add logging errors to file
This commit is contained in:
zefie
2021-07-25 10:12:36 -04:00
parent e591d255b7
commit c4e3e0fb99
11 changed files with 248 additions and 174 deletions

View File

@@ -1,13 +1,6 @@
headers = `200 OK`;
if (request_headers.query.nick) headers += `
wtv-irc-nick: ${request_headers.query.nick}
wtv-user-nick: ${request_headers.query.nick}`
;
headers += `
Content-Type: text/html`;
headers = "200 OK";
if (request_headers.query.nick) headers += "\n" + ssid_sessions[socket.ssid].setIRCNick(request_headers.query.nick);
headers += "\nContent-Type: text/html";
if (request_headers.query.host && request_headers.query.port && request_headers.query.channel) {
data = `<html>
@@ -46,16 +39,6 @@ ${request_headers.query.channel}
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
<td width=5>
<tr> <td bgcolor=#2E3A54 height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
<td width=5>
<tr> <td bgcolor=#2E3A54 height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
<table cellspacing=0 cellpadding=0 href="javascript:void(window.open('newChatChannel.panel'))" >
<tr>
<td height=1>
@@ -120,12 +103,9 @@ ${request_headers.query.channel}
<tr>
<td><img src="wtv-chat:/images/widget.gif" width=16 height=16>
<td width=3>
<td width=54>
<td width=84>
<spacer type=vertical size=1><br>
<a href="wtv-chat:/type"><font size=-1 color=#E7CE4A><b> Go to</b></font></a>
<td width=21>
<img src="wtv-chat:/images/widget.gif" width=16 height=16>
<td width=34>
<a href="wtv-chat:/home"><font size=-1 color=#E7CE4A><b> Home</b></font></a>
</table>
</table>
</table>

View File

@@ -1,123 +0,0 @@
<html>
<head>
<title>
Chat Home
</title>
</head>
<body bgcolor="#101C1E" text="#A2ACB5" link="#CFC382" vlink="#E1EOE3" fontsize="medium" vspace=0 hspace=0>
<sidebar width=109>
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=420 bgcolor=#777896 valign=top>
<table cellspacing=0 cellpadding=0>
<tr>
<td height=7 colspan=3>
<spacer type=vertical size=7>
<tr>
<td width=7>
<spacer type=horizontal size=7>
<td width=87 href="wtv-home:/home">
<img src="images/htv_chat.gif" width=87 height=67>
<td width=10>
<spacer type=horizontal size=10>
</table>
<spacer type=vertical size=6>
<table cellspacing=0 cellpadding=0 border=0>
<tr> <td bgcolor=#2E3A54 height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
<td width=5>
</table>
<td width=5 bgcolor=#2E3A54>
</table>
</sidebar>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=451 colspan=2 align=center bgcolor=#2E3A54>
<spacer type=vertical size=13>
<tr>
<td><img src="wtv-chat:/images/top_corner_dark.jpg" width=8 height=8>
<td width=60>
<tr>
<td bgcolor=#101C1E width=13>
<spacer type=horizontal size=13>
<td bgcolor=#101C1E width=438 valign=top>
<table cellspacing=0 cellpadding=0>
<tr>
<td width=105 height=9><spacer type=vertical size=9>
<td>
</table>
<tr>
<td colspan=2>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=375 height=25 bgcolor=#101C1E gradcolor=#3C4652 gradangle=90>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=366 valign=middle>&nbsp;&nbsp;
<blackface><font color=#D6D6D6>
</font></blackface><td>
<table cellspacing=0 cellpadding=0 border=0 bgcolor=#3C4652 gradcolor=#2E3A54 gradangle=90>
<tr>
<td height=16>
<td width=3>
<td width=100>
<spacer type=vertical size=2><br>
<font size=2 color=#E7CE4A><b>Chat Home</b></font>
<td width=21>
<td width=34>
</table>
</table>
</table>
<spacer type=vertical size=12> <table cellspacing=0 cellpadding=0>
<tr>
<td colspan=3 height=12>
<spacer type=vertical size=12> <tr>
<td abswidth=14>
<td>
yo yo yo yo
enter your nick...
<td abswidth=20>
<tr>
<td height=10>
<td>
<td colspan=2 height=2>
<spacer>
<tr>
<td height=1>
<tr>
<td>
<td colspan=2 height=2>
<spacer>
<tr>
<td height=230><!--yo yo yo Change this if needed-->
</table>
<table cellspacing=0 cellpadding=0 width=100%>
<tr>
<form action="wtv-chat:/MakeChatPage?host=chat.irchat.tv&port=6667&channel=WebTV" ONSUBMIT="this.chatinput.focus()">
<td abswidth=14>
<td>
<input id="chatinput" name="nick" type="text" value="" size=32 bgcolor=262626 text=ffc342 cursor=cc9933 font=proportional selected autoactivate nohighlight>
<td align=right>
<font color=e7ce4a><shadow>
<input type=submit borderimage="file://ROM/Borders/ButtonBorder2.bif" value="Join" usestyle width=80>
<td abswidth=9>
</form>
<tr> <TD HEIGHT=8>
</table>
</body>
</html>

View File

@@ -0,0 +1,144 @@
var irc_nick = "";
headers = "200 OK";
if (request_headers.query.nick) headers += "\n" + ssid_sessions[socket.ssid].setIRCNick(request_headers.query.nick);
else if (!ssid_sessions[socket.ssid].get("wtv-irc-nick")) ssid_sessions[socket.ssid].setIRCNick(minisrv_config.config.service_name + '_' + Math.floor(Math.random() * 100000)).substring(0, 16);
headers += "\nContent-Type: text/html";
var irc_nick = ssid_sessions[socket.ssid].get("wtv-irc-nick");
data = `<html>
<head>
<title>
Chat Home (Testing)
</title>
</head>
<body bgcolor="#101C1E" text="#A2ACB5" link="#CFC382" vlink="#E1EOE3" fontsize="medium" vspace=0 hspace=0>
<display noscroll>
<sidebar width=109>
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=420 bgcolor=#69758B valign=top>
<table cellspacing=0 cellpadding=0>
<tr>
<td height=7 colspan=3>
<spacer type=vertical size=7>
<tr>
<td width=7>
<spacer type=horizontal size=7>
<td width=87 href="wtv-home:/home">
<img src="${minisrv_config.config.service_logo}" width=87 height=67>
<td width=10>
<spacer type=horizontal size=10>
</table>
<spacer type=vertical size=6>
<table cellspacing=0 cellpadding=0 border=0>
<tr> <td bgcolor=#2E3A54 height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
<table cellspacing=0 cellpadding=0 href="client:relog" >
<tr>
<td height=1>
<tr>
<td><shadow><font sizerange=medium color=#E1EOE3>Relogin</font></shadow>
</table>
<td width=5>
<tr> <td bgcolor=#2E3A54 height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
<table cellspacing=0 cellpadding=0 href="wtv-home:/home" >
<tr>
<td height=1>
<tr>
<td><shadow><font sizerange=medium color=#E1EOE3>Home</font></shadow>
</table>
<td width=5>
<tr> <td bgcolor=#2E3A54 height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=89 valign=middle>
</table>
<td width=5 bgcolor=#2E3A54>
</table>
</sidebar>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=451 colspan=2 align=center bgcolor=#2E3A54>
<spacer type=vertical size=13>
<tr>
<td><img src="wtv-chat:/images/top_corner_dark.jpg" width=8 height=8>
<td width=60>
<tr>
<td bgcolor=#101C1E width=13>
<spacer type=horizontal size=13>
<td bgcolor=#101C1E width=438 valign=top>
<table cellspacing=0 cellpadding=0>
<tr>
<td width=105 height=9><spacer type=vertical size=9>
<td>
</table>
<tr>
<td colspan=2>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=375 height=25 bgcolor=#101C1E gradcolor=#3C4652 gradangle=90>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=366 valign=middle>&nbsp;&nbsp;
<blackface><font color=#D6D6D6>
</font></blackface><td>
<table cellspacing=0 cellpadding=0 border=0 bgcolor=#3C4652 gradcolor=#2E3A54 gradangle=90>
<tr>
<td width=21>
<td width=400>
<td width=34>
</table>
</table>
</table>
<spacer type=vertical size=12> <table cellspacing=0 cellpadding=0>
<tr>
<td colspan=3 height=12>
<spacer type=vertical size=22> <tr>
<td abswidth=14>
<td abswidth=400>
<form action="wtv-chat:/MakeChatPage" method="get">
<table>
<tr>
<td abswidth="120">Server:</td>
<td><input width="240" bgcolor=262626 text=ffc342 cursor=cc9933 font=proportional usestyle type="text" name="host" value="${request_headers.query.host || "chat.irchat.tv"}"></td>
</tr>
<tr>
<td>Port:</td>
<td><input width="240" bgcolor=262626 text=ffc342 cursor=cc9933 font=proportional usestyle type="text" name="port" value="${request_headers.query.port || 6667}"></td>
</tr>
<tr>
<td>Channel:</td>
<td><input width="240" bgcolor=262626 text=ffc342 cursor=cc9933 font=proportional usestyle type="text" name="channel" value="${request_headers.query.channel || "WebTV"}"></td>
</tr>
<tr>
<td>IRC Nick<sup>*</sup>:</td>
<td><input width="240" bgcolor=262626 text=ffc342 cursor=cc9933 font=proportional usestyle maxlength=16 type="text" name="nick" value="${irc_nick}"></td>
</tr>
<tr>
<td colspan="2" align="right">
<input type=submit borderimage="file://ROM/Borders/ButtonBorder2.bif" value="Connect" usestyle width=100>
</td>
</tr>
</table>
<br>
<small><sup>*</sup>Note: Once you are connected to the IRC Server, you cannot change your nickname until you disconnect.
What triggers the WebTV to disconnect from the chat server is not yet known,
it does maintain a connection to the IRC server, but leaves the channel, when you leave the chat page.
The connection times out after some time. Only then will any future attempts to change your name work.</small>
<td abswidth=9>
</form>
<tr> <TD HEIGHT=8>
</table>
</body>
</html>`;

View File

@@ -47,8 +47,8 @@ Content-type: text/html`;
}
else {
var namerand = Math.floor(Math.random() * 100000);
var nickname = (minisrv_config.config.service_name + '_' + namerand).substring(0, 16);
var userid = '1'+ Math.floor(Math.random() * 1000000000000000000);
var nickname = (minisrv_config.config.service_name + '_' + namerand)
var userid = '1' + Math.floor(Math.random() * 1000000000000000000);
var offline_user_list = CryptoJS.enc.Latin1.parse("<user-list>\n\t<user userid=\"" + userid + " user-name=\"" + nickname + "\" first-name=\"" + minisrv_config.config.service_name + "User \" last-name=\\" + namerand + "\" password=\"\" mail-enabled=\"true\" />\n</user-list>").toString(CryptoJS.enc.Base64);
data = '';
headers = `200 OK
@@ -77,9 +77,8 @@ wtv-noback-all: wtv-
wtv-service: reset
`+ getServiceString('all') + `
wtv-boot-url: wtv-1800:/preregister?relogin=true
wtv-user-name: ${nickname}
wtv-human-name: ${nickname}
wtv-irc-nick: ${nickname}
${ssid_sessions[socket.ssid].setIRCNick(nickname)}
wtv-home-url: wtv-home:/home?
wtv-domain: wtv.zefie.com
wtv-inactive-timeout: 0

View File

@@ -11,7 +11,7 @@ if (ssid_sessions[socket.ssid].get('box-does-psuedo-encryption')) {
}
data =`<html>
data = `<html>
<head>
<title>Home for minisrv</title>
<DISPLAY NoLogo hideoptions noscroll>
@@ -29,12 +29,25 @@ function go() {
<form name=access onsubmit="go()">
<ul>
<li><a href="client:relog">client:relog (direct)</a> ~ <a href="wtv-tricks:/blastcache?return_to=wtv-home:/home">Clear Cache</a></li>
<li><a href="client:diskhax">DiskHax</a> ~ <a href="client:vfathax">VFatHax</a></li>
<li><a href="wtv-flashrom:/willie" selected>Ultra Willies</a> ~ <a href="wtv-tricks:/info">Tricks Info</a></li>
<li><a href="wtv-music:/demo/index">MIDI Music Demo</a></li>
<li>Old MSNTV DealerDemo: <a href="wtv-update:/DealerDemo">Download</a> ~ <a href="file://Disk/Demo/index.html">Access (after Download)</a></li>
<li><a href="http://duckduckgo.com/lite/">DuckDuckGo Lite</a></li>`
if (ssid_sessions[socket.ssid].get('wtv-need-upgrade') != 'true') {
`;
if (ssid_sessions[socket.ssid].hasCap("client-can-do-chat")) {
data += "<li><a href=\"wtv-chat:/home\">IRC Chat Test</a></li>\n"
}
if (ssid_sessions[socket.ssid].hasCap("client-has-disk")) {
// only show disk stuff if client has disk
data += "<li><a href=\"client:diskhax\">DiskHax</a> ~ <a href=\"client:vfathax\">VFatHax</a></li>\n";
if (ssid_sessions[socket.ssid].hasCap("client-can-do-macromedia-flash2")) {
// only show demo if client can do flash2
data += "<li>Old MSNTV DealerDemo: <a href=\"wtv-update:/DealerDemo\">Download</a> ~ <a href=\"file://Disk/Demo/index.html\"> Access (after Download)</a></li>\n";
}
}
data += `<li><a href="http://duckduckgo.com/lite/">DuckDuckGo Lite</a></li>`
if (ssid_sessions[socket.ssid].hasCap("client-can-do-javascript")) {
// URL access form requires javascript, hide if client does not support
data += `<li><input name=url `;
if (request_headers.query.url) {
@@ -43,7 +56,7 @@ if (ssid_sessions[socket.ssid].get('wtv-need-upgrade') != 'true') {
data += `width=250 height=10 bgcolor=#444444 text=#ffdd33 cursor=#cc9933>
<input type=submit value="Access URL">
</form>`
</form>`;
}
data += "</li >\n</ul>";

View File

@@ -118,9 +118,8 @@ class WTVClientCapabilities {
// convert wtv_capability_flags to binary string, reverse the string, and split into array containing each character;
var bitfield = hex2bin(wtv_capability_flags).reverse().split("");
// only add to the capabilities array if the result is true
var add = function (flag_name, flag) {
if (flag) capabilities[flag_name] = flag;
capabilities[flag_name] = flag;
}
// process bitfield and set capabilities

View File

@@ -9,11 +9,48 @@ class WTVClientSessionData {
\***********************************/
data_store = null;
capabilities = null;
constructor() {
this.data_store = new Array();
}
hasCap(cap) {
if (this.capabilities) {
return this.capabilities[cap] || false;
}
return false;
}
getMaxUsernameLength() {
if (parseInt(this.data_store['wtv-system-version'] < 4000)) {
// older builds may crash with nicknames longer than 16 chars.
// actual build where support started is yet unknown
return 16;
} else {
// newer builds supported up to 32 chars, I think
return 32;
}
}
setIRCNick(nick) {
// strip out unsupported chars
nick = nick.replace(/[^a-zA-Z0-9\-\_\`\^]/g, "");
// limit nick length based on build support
nick = nick.substring(0, this.getMaxUsernameLength());
// returns headers to send to client, while storing the new data in our session data.
this.data_store['wtv-user-name'] = nick;
this.data_store['wtv-irc-nick'] = nick;
return "wtv-irc-nick: " + nick + "\nwtv-user-nick: " + nick;
}
isMiniBrowser() {
if (this.data_store['wtv-need-upgrade'] || this.data_store['wtv-used-8675309']) return true;
return false;
}
get(key = null) {
if (typeof (this.data_store) === 'undefined') return null;
else if (key === null) return this.data_store;

View File

@@ -9,6 +9,7 @@ const net = require('net');
const CryptoJS = require('crypto-js');
const mime = require('mime-types');
const { crc16 } = require('easy-crc');
const process = require('process');
var WTVSec = require('./WTVSec.js');
var WTVClientCapabilities = require('./WTVClientCapabilities.js');
var WTVClientSessionData = require('./WTVClientSessionData.js');
@@ -71,6 +72,7 @@ function doErrorPage(code, data = null) {
headers += "Content-Type: text/html\r\n";
break;
}
console.error("doErrorPage Called:", code, data);
return new Array(headers, data);
}
@@ -166,11 +168,11 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1] + "<br><br>The interpreter said:<br><pre>" + e.toString() + "</pre>";
console.log(" * Scripting error:",e);
console.error(" * Scripting error:",e);
}
if (!request_is_async) {
if (!service_vault_found) {
console.log(" * Could not find a Service Vault for " + service_name + ":/" + service_path.replace(service_name + path.sep, ""));
console.error(" * Could not find a Service Vault for " + service_name + ":/" + service_path.replace(service_name + path.sep, ""));
var errpage = doErrorPage(404);
headers = errpage[0];
data = errpage[1];
@@ -179,8 +181,8 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1];
console.log(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
console.log(socket.id, headers, data)
console.error(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
console.error(socket.id, headers, data)
}
if (data === null) {
data = '';
@@ -215,6 +217,7 @@ function filterSSID(obj) {
function makeSafePath(base, target) {
target.replace(/[\|\&\;\$\%\@\"\<\>\+\,\\]/g, "");
if (path.sep != "/") target = target.replace(/\//g, path.sep);
var targetPath = path.posix.normalize(target)
return base + path.sep + targetPath;
}
@@ -729,7 +732,7 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq
if (!ssid_sessions[socket.ssid]) {
ssid_sessions[socket.ssid] = new WTVClientSessionData();
}
if (!ssid_sessions[socket.ssid].data_store.capabilities) ssid_sessions[socket.ssid].data_store.capabilities = new WTVClientCapabilities(headers["wtv-capability-flags"]);
if (!ssid_sessions[socket.ssid].capabilities) ssid_sessions[socket.ssid].capabilities = new WTVClientCapabilities(headers["wtv-capability-flags"]);
}
@@ -1058,7 +1061,7 @@ async function cleanupSocket(socket) {
}
socket.end();
} catch (e) {
console.log(" # Could not clean up socket data for socket ID", socket.id, e);
console.error(" # Could not clean up socket data for socket ID", socket.id, e);
}
}
@@ -1068,7 +1071,7 @@ async function handleSocket(socket) {
socket.id = parseInt(crc16('CCITT-FALSE', Buffer.from(String(socket.remoteAddress) + String(socket.remotePort), "utf8")).toString(16), 16);
socket_sessions[socket.id] = [];
socket.setEncoding('hex'); //set data encoding (Text: 'ascii', 'utf8' ~ Binary: 'hex', 'base64' (do not trust 'binary' encoding))
socket.setTimeout(600000);
socket.setTimeout(10800000); // 3 hours
socket.on('data', function (data_hex) {
if (!socket_sessions[socket.id].secure && !socket_sessions[socket.id].expecting_post_data) {
// buffer unencrypted data until we see the classic double-newline, or get blank
@@ -1120,7 +1123,7 @@ function integrateConfig(main, user) {
return main;
}
function returnAbsolsutePath(check_path) {
function returnAbsolutePath(check_path) {
if (check_path.substring(0, 1) != path.sep && check_path.substring(1, 1) != ":") {
// non-absolute path, so use current directory as base
check_path = (__dirname + path.sep + check_path);
@@ -1170,7 +1173,7 @@ try {
try {
var minisrv_user_config = JSON.parse(fs.readFileSync(__dirname + "/user_config.json"));
} catch (e) {
console.log("ERROR: Could not read user_config.json", e);
console.error("ERROR: Could not read user_config.json", e);
var throw_me = true;
}
// file exists and we read and parsed it, but the variable is undefined
@@ -1178,11 +1181,11 @@ try {
try {
minisrv_config = integrateConfig(minisrv_config, minisrv_user_config)
} catch (e) {
console.log("ERROR: Could not read user_config.json", e);
console.error("ERROR: Could not read user_config.json", e);
}
}
} catch (e) {
if (zdebug) console.log(" * Notice: Could not find user configuration (user_config.json). Using default configuration.");
if (zdebug) console.error(" * Notice: Could not find user configuration (user_config.json). Using default configuration.");
}
if (throw_me) {
@@ -1191,7 +1194,7 @@ if (throw_me) {
if (minisrv_config.config.ServiceVaults) {
Object.keys(minisrv_config.config.ServiceVaults).forEach(function (k) {
var service_vault = returnAbsolsutePath(minisrv_config.config.ServiceVaults[k]);
var service_vault = returnAbsolutePath(minisrv_config.config.ServiceVaults[k]);
service_vaults.push(service_vault);
console.log(" * Configured Service Vault at", service_vault, "with priority",(parseInt(k)+1));
})
@@ -1231,6 +1234,19 @@ if (minisrv_config.config.service_logo.indexOf(':') == -1) minisrv_config.config
if (minisrv_config.config.service_splash_logo.indexOf(':') == -1) minisrv_config.config.service_splash_logo = "wtv-star:/ROMCache/" + minisrv_config.config.service_splash_logo;
minisrv_config.version = require('./package.json').version;
if (minisrv_config.config.error_log_file) {
var error_log_stream = fs.createWriteStream(returnAbsolutePath(minisrv_config.config.error_log_file), { flags: 'a' });
var process_stderr = process.stderr.write;
var writeError = function() {
process_stderr.apply(process.stderr, arguments);
if (error_log_stream) error_log_stream.write.apply(error_log_stream, arguments);
}
process.stderr.write = writeError
}
process.on('uncaughtException', function (err) {
console.error((err && err.stack) ? err.stack : err);
});
// defaults
var zdebug = false;
@@ -1289,6 +1305,8 @@ bind_ports.forEach(function (v) {
});
initstring = initstring.substring(0, initstring.length - 2);
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";
console.log(" * Listening on", listening_ip_string,"~","Service IP:", service_ip);

View File

@@ -10,7 +10,8 @@
"service_splash_logo": "splash_logo_msn.gif",
"hide_ssid_in_logs": true,
"post_percentages": [ 0, 25, 50, 100],
"verbosity": 2
"verbosity": 2,
"error_log_file": "errors.log"
},
"services": {
"wtv-1800": {

View File

@@ -1,6 +1,6 @@
{
"name": "zefie_wtvp_minisrv",
"version": "0.9.6",
"version": "0.9.7",
"description": "WebTV Service (WTVP) Emulation Server",
"main": "app.js",
"homepage": "https://github.com/zefie/zefie_wtvp_minisrv",

View File

@@ -32,6 +32,11 @@
<Content Include=".gitignore" />
<Content Include="app.js" />
<Content Include="config.json" />
<Content Include="ServiceVault\wtv-chat\home.js" />
<Content Include="ServiceVault\wtv-chat\images\htv_chat.gif" />
<Content Include="ServiceVault\wtv-chat\images\htv_chat.jpg" />
<Content Include="ServiceVault\wtv-chat\images\top_corner_dark.jpg" />
<Content Include="ServiceVault\wtv-chat\images\widget.gif" />
<Content Include="ServiceVault\wtv-chat\MakeChatPage.js" />
<Content Include="ServiceVault\wtv-flashrom\get-by-path.js">
<SubType>Code</SubType>
@@ -219,6 +224,7 @@
<ItemGroup>
<Folder Include="ServiceVault\" />
<Folder Include="ServiceVault\wtv-chat\" />
<Folder Include="ServiceVault\wtv-chat\images\" />
<Folder Include="ServiceVault\wtv-flashrom\" />
<Folder Include="ServiceVault\wtv-flashrom\ROMCache\" />
<Folder Include="ServiceVault\wtv-music\" />