add catchall system & http pc server
- define a catchall name to run globally or per service - catchall must be javascript, but not necessarily a .js file - catchall can request async mode - catchall will catch any non-existing requests under its directory - see wtv-flashrom:/content/content-serve.js as an example, which will catch wtv-flashrom:/content/ URLs. - http pc: sends HTTP/1.0 to PC clients - can be disabled with `pc_server_hidden_service_enabled`: false - can change servicevault path by changing string of pc_server_hidden_service - get.js in default PC service vault to get any WTV Url on the service
This commit is contained in:
@@ -22,6 +22,10 @@ If you would like to see debug information about realtime bytes received from a
|
|||||||
"allow_guests": false
|
"allow_guests": false
|
||||||
```
|
```
|
||||||
If you would like to require registration, disabling guest mode, you can set `allow_guests` to `false`. Default is `true`;
|
If you would like to require registration, disabling guest mode, you can set `allow_guests` to `false`. Default is `true`;
|
||||||
|
```
|
||||||
|
"pc_server_hidden_service": false
|
||||||
|
```
|
||||||
|
Set this option to false to disable the HTTP Server for Browsers. Set it to a string to use that directory under the service vaults.
|
||||||
```
|
```
|
||||||
"post_percentages": [ 0, 25, 50, 100]
|
"post_percentages": [ 0, 25, 50, 100]
|
||||||
```
|
```
|
||||||
|
|||||||
37
zefie_wtvp_minisrv/ServiceVault/http_pc/get.js
Normal file
37
zefie_wtvp_minisrv/ServiceVault/http_pc/get.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
if (request_headers.query.url) {
|
||||||
|
if (request_headers.query.url.indexOf(":/") > 0) {
|
||||||
|
var service_request = request_headers.query.url.split(":/")[0];
|
||||||
|
var service_port = 0;
|
||||||
|
Object.keys(minisrv_config.services).forEach(function (k) {
|
||||||
|
if (minisrv_config.services[k].disabled) return;
|
||||||
|
if (k == service_request) service_port = minisrv_config.services[k].port;
|
||||||
|
});
|
||||||
|
if (service_port > 0) {
|
||||||
|
request_is_async = true;
|
||||||
|
var request_headers_out = new Array()
|
||||||
|
request_headers_out.request = "GET " + request_headers.query.url;
|
||||||
|
request_headers_out.request_url = request_headers.query.url;
|
||||||
|
request_headers_out['wtv-client-serial-number'] = socket.id + "HTTPPCReq";
|
||||||
|
processURL(socket, request_headers_out);
|
||||||
|
/*
|
||||||
|
var s = require('net').Socket();
|
||||||
|
var outdata = "";
|
||||||
|
s.connect(service_port);
|
||||||
|
s.setTimeout(1, function () {
|
||||||
|
outdata = outdata.split()
|
||||||
|
sendToClient(socket,outdata);
|
||||||
|
});
|
||||||
|
s.on('data', function (data) {
|
||||||
|
outdata += data;
|
||||||
|
});
|
||||||
|
s.write()
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!headers) {
|
||||||
|
var errpage = doErrorPage(500)
|
||||||
|
headers = errpage[0];
|
||||||
|
data = errpage[1];
|
||||||
|
}
|
||||||
31
zefie_wtvp_minisrv/ServiceVault/http_pc/index.js
Normal file
31
zefie_wtvp_minisrv/ServiceVault/http_pc/index.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
headers = `200 OK
|
||||||
|
Content-Type: text/html`
|
||||||
|
|
||||||
|
var splash_logo = minisrv_config.config.service_splash_logo;
|
||||||
|
if (splash_logo.substring(0, 4) == "file") splash_logo = "wtv-star:/ROMCache/splash_logo_hacktv.gif";
|
||||||
|
|
||||||
|
data = `<html>
|
||||||
|
<head>
|
||||||
|
<display hideoptions nostatus showwhencomplete skipback clearback fontsize=medium>
|
||||||
|
<title>zefie minisrv ${minisrv_config.version}</title>
|
||||||
|
<meta http-equiv=Refresh content="4; url=wtv-home:/home?">
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#000000" text="#449944">
|
||||||
|
<center>
|
||||||
|
<spacer type=block height=88 width=21>
|
||||||
|
<img src="/get?url=${escape('wtv-star:/ROMCache/spacer.gif')}" height=4><br>
|
||||||
|
<img src="/get?url=${escape(splash_logo)}">
|
||||||
|
<br><br><br>
|
||||||
|
<p><br>
|
||||||
|
<p><br>
|
||||||
|
<table border>
|
||||||
|
<tr><td width=150>
|
||||||
|
Mini service
|
||||||
|
<tr><td>
|
||||||
|
zefie minisrv v${minisrv_config.version}`;
|
||||||
|
if (minisrv_config.config.git_commit) data += " (git " + minisrv_config.config.git_commit + ")";
|
||||||
|
data += `
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const WTVFlashrom = require("./WTVFlashrom.js");
|
||||||
|
request_is_async = true;
|
||||||
|
console.log(request_headers);
|
||||||
|
|
||||||
|
var bf0app_update = false;
|
||||||
|
var request_path = request_headers.request_url.replace(service_name + ":/", "");
|
||||||
|
var romtype = ssid_sessions[socket.ssid].get("wtv-client-rom-type");
|
||||||
|
var bootver = ssid_sessions[socket.ssid].get("wtv-client-bootrom-version")
|
||||||
|
|
||||||
|
if ((romtype == "bf0app" || !romtype) && (bootver == "105" || !bootver)) {
|
||||||
|
// assume old classic in flash mode, override user setting and send tellyscript
|
||||||
|
// because it is required to proceed in flash mode
|
||||||
|
bf0app_update = true;
|
||||||
|
ssid_sessions[socket.ssid].set("bf0app_update", bf0app_update);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ssid_sessions[socket.ssid].data_store.WTVFlashrom) {
|
||||||
|
ssid_sessions[socket.ssid].data_store.WTVFlashrom = new WTVFlashrom(service_vaults, service_name, minisrv_config.services[service_name].use_zefie_server, bf0app_update, minisrv_config.services[service_name].debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid_sessions[socket.ssid].data_store.WTVFlashrom.getFlashRom(request_path, function (data, headers) {
|
||||||
|
sendToClient(socket, headers, data);
|
||||||
|
});
|
||||||
@@ -117,7 +117,7 @@ class WTVFlashrom {
|
|||||||
flashrom_info.message = new Buffer.from(part_header.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, "");
|
flashrom_info.message = new Buffer.from(part_header.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, "");
|
||||||
|
|
||||||
flashrom_info.is_last_part = ((flashrom_info.byte_progress + flashrom_info.part_total_size) == flashrom_info.total_parts_size) ? true : false;
|
flashrom_info.is_last_part = ((flashrom_info.byte_progress + flashrom_info.part_total_size) == flashrom_info.total_parts_size) ? true : false;
|
||||||
flashrom_info.rompath = 'wtv-flashrom:/get-by-path?path=' + path + '&raw=true';
|
flashrom_info.rompath = `wtv-flashrom:/${path}`;
|
||||||
if (this.zdebug) console.log(" # Flashrom Part Bytes Sent (after this part):", flashrom_info.byte_progress + flashrom_info.part_total_size);
|
if (this.zdebug) console.log(" # Flashrom Part Bytes Sent (after this part):", flashrom_info.byte_progress + flashrom_info.part_total_size);
|
||||||
if (this.zdebug) console.log(" # Flashrom Part is Last Part", flashrom_info.is_last_part);
|
if (this.zdebug) console.log(" # Flashrom Part is Last Part", flashrom_info.is_last_part);
|
||||||
|
|
||||||
|
|||||||
@@ -74,24 +74,31 @@ function getFileExt(path) {
|
|||||||
return path.reverse().split(".")[0].reverse();
|
return path.reverse().split(".")[0].reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
function doErrorPage(code, data = null) {
|
function doErrorPage(code, data = null, pc_mode = false) {
|
||||||
var headers = null;
|
var headers = null;
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 404:
|
case 404:
|
||||||
if (data === null) data = "The service could not find the requested page.";
|
if (data === null) data = "The service could not find the requested page.";
|
||||||
headers = "404 " + data + "\r\n";
|
if (pc_mode) headers = "404 Not Found\n";
|
||||||
headers += "Content-Type: text/html\r\n";
|
else headers = code + " "+ data + "\n";
|
||||||
|
headers += "Content-Type: text/html\n";
|
||||||
break;
|
break;
|
||||||
case 400:
|
case 400:
|
||||||
|
case 500:
|
||||||
if (data === null) data = "HackTV ran into a technical problem.";
|
if (data === null) data = "HackTV ran into a technical problem.";
|
||||||
headers = "400 " + data + "\r\n";
|
if (pc_mode) headers = "500 Internal Server Error\n";
|
||||||
headers += "Content-Type: text/html\r\n";
|
else headers = code + " " + data + "\n";
|
||||||
|
headers += "Content-Type: text/html\n";
|
||||||
|
break;
|
||||||
|
case 401:
|
||||||
|
if (data === null) data = "Access Denied.";
|
||||||
|
if (pc_mode) headers = "401 Access Denied\n";
|
||||||
|
else headers = code + " " + data + "\n";
|
||||||
|
headers += "Content-Type: text/html\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// what we send when we did not detect a wtv-url.
|
headers = code + " " + data + "\n";
|
||||||
// e.g. when a pc browser connects
|
headers += "Content-Type: text/html\n";
|
||||||
headers = "HTTP/1.1 200 OK\r\n";
|
|
||||||
headers += "Content-Type: text/html\r\n";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
console.error("doErrorPage Called:", code, data);
|
console.error("doErrorPage Called:", code, data);
|
||||||
@@ -175,8 +182,25 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
|
|||||||
try {
|
try {
|
||||||
service_vaults.forEach(function (service_vault_dir) {
|
service_vaults.forEach(function (service_vault_dir) {
|
||||||
if (service_vault_found) return;
|
if (service_vault_found) return;
|
||||||
service_vault_file_path = makeSafePath(service_vault_dir,service_path);
|
service_vault_file_path = makeSafePath(service_vault_dir, service_path);
|
||||||
|
|
||||||
|
// deny access to catchall file name directly
|
||||||
|
var service_path_split = service_path.split("/");
|
||||||
|
var service_path_request_file = service_path_split[service_path_split.length - 1];
|
||||||
|
if (minisrv_config.config.catchall_file_name) {
|
||||||
|
var minisrv_catchall = null;
|
||||||
|
if (minisrv_config.services[service_name]) minisrv_catchall = minisrv_config.services[service_name].catchall_file_name || minisrv_config.config.catchall_file_name || null;
|
||||||
|
else minisrv_catchall = minisrv_config.config.catchall_file_name || null;
|
||||||
|
if (minisrv_catchall) {
|
||||||
|
if (service_path_request_file == minisrv_catchall) {
|
||||||
|
var errpage = doErrorPage(401, "Access Denied");
|
||||||
|
headers = errpage[0];
|
||||||
|
data = errpage[1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
minisrv_catchall, service_path_split, service_path_request_file = null;
|
||||||
|
|
||||||
if (fs.existsSync(service_vault_file_path)) {
|
if (fs.existsSync(service_vault_file_path)) {
|
||||||
// file exists, read it and return it
|
// file exists, read it and return it
|
||||||
@@ -242,6 +266,31 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
|
|||||||
fs.readFile(service_vault_file_path + ".html", null, function (err, data) {
|
fs.readFile(service_vault_file_path + ".html", null, function (err, data) {
|
||||||
sendToClient(socket, headers, data);
|
sendToClient(socket, headers, data);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// look for a catchallin the current path and all parent paths up until the service root
|
||||||
|
if (minisrv_config.config.catchall_file_name) {
|
||||||
|
var minisrv_catchall_file_name = null;
|
||||||
|
if (minisrv_config.services[service_name]) minisrv_catchall_file_name = minisrv_config.services[service_name].catchall_file_name || minisrv_config.config.catchall_file_name || null;
|
||||||
|
else minisrv_catchall_file_name = minisrv_config.config.catchall_file_name || null;
|
||||||
|
if (minisrv_catchall_file_name) {
|
||||||
|
var service_check_dir = service_vault_file_path.split(path.sep);
|
||||||
|
service_check_dir.pop(); // pop filename
|
||||||
|
|
||||||
|
while (service_check_dir.join(path.sep) != service_vault_dir) {
|
||||||
|
var catchall_file = service_check_dir.join(path.sep) + path.sep + minisrv_catchall_file_name;
|
||||||
|
if (fs.existsSync(catchall_file)) {
|
||||||
|
if (!zquiet) console.log(" * Found catchall at " + catchall_file + ".html to handle request (HTML Mode) [Socket " + socket.id + "]");
|
||||||
|
var jscript_eval = fs.readFileSync(catchall_file).toString();
|
||||||
|
// don't pass these vars to the script
|
||||||
|
var service_check_dir, minisrv_catchall_file_name = null;
|
||||||
|
eval(jscript_eval);
|
||||||
|
if (request_is_async && !zquiet) console.log(" * Script requested Asynchronous mode");
|
||||||
|
} else {
|
||||||
|
service_check_dir.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// either `request_is_async`, or `headers` and `data` MUST be defined by this point!
|
// either `request_is_async`, or `headers` and `data` MUST be defined by this point!
|
||||||
});
|
});
|
||||||
@@ -254,12 +303,12 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
|
|||||||
if (!request_is_async) {
|
if (!request_is_async) {
|
||||||
if (!service_vault_found) {
|
if (!service_vault_found) {
|
||||||
console.error(" * 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);
|
var errpage = doErrorPage(404, null, socket.minisrv_pc_mode);
|
||||||
headers = errpage[0];
|
headers = errpage[0];
|
||||||
data = errpage[1];
|
data = errpage[1];
|
||||||
}
|
}
|
||||||
if (headers == null && !request_is_async) {
|
if (headers == null && !request_is_async) {
|
||||||
var errpage = doErrorPage(400);
|
var errpage = doErrorPage(400, null, socket.minisrv_pc_mode);
|
||||||
headers = errpage[0];
|
headers = errpage[0];
|
||||||
data = errpage[1];
|
data = errpage[1];
|
||||||
console.error(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
|
console.error(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
|
||||||
@@ -300,7 +349,7 @@ function filterSSID(obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeSafeSSID(ssid) {
|
function makeSafeSSID(ssid = "") {
|
||||||
ssid = ssid.replace(/[^a-zA-Z0-9]/g, "");
|
ssid = ssid.replace(/[^a-zA-Z0-9]/g, "");
|
||||||
if (ssid.length == 0) ssid = null;
|
if (ssid.length == 0) ssid = null;
|
||||||
return ssid;
|
return ssid;
|
||||||
@@ -313,10 +362,21 @@ function makeSafePath(base, target) {
|
|||||||
return base + path.sep + targetPath;
|
return base + path.sep + targetPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processURL(socket, request_headers) {
|
function getServiceBySocket(socket) {
|
||||||
if (request_headers === null) {
|
var socket_port = socket.server._connectionKey;
|
||||||
return;
|
if (socket_port) {
|
||||||
|
socket_port = socket.server._connectionKey.split(":")[2];
|
||||||
|
var service_name = null;
|
||||||
|
Object.keys(minisrv_config.services).forEach(function (k) {
|
||||||
|
if (minisrv_config.services[k].disabled) return;
|
||||||
|
if (minisrv_config.services[k].port == socket_port) service_name = k;
|
||||||
|
});
|
||||||
|
return service_name;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processURL(socket, request_headers) {
|
||||||
var shortURL, headers, data = "";
|
var shortURL, headers, data = "";
|
||||||
request_headers.query = new Array();
|
request_headers.query = new Array();
|
||||||
if (request_headers.request_url) {
|
if (request_headers.request_url) {
|
||||||
@@ -372,6 +432,32 @@ async function processURL(socket, request_headers) {
|
|||||||
shortURL_split.shift();
|
shortURL_split.shift();
|
||||||
var shortURL_service_path = shortURL_split.join(":");
|
var shortURL_service_path = shortURL_split.join(":");
|
||||||
shortURL = shortURL_service_name + ":/" + shortURL_service_path;
|
shortURL = shortURL_service_name + ":/" + shortURL_service_path;
|
||||||
|
} else if (shortURL.indexOf(":") == -1 && request_headers.request.indexOf("HTTP/1") > 0) {
|
||||||
|
// is this an odd WTVP request or HTTP Request?
|
||||||
|
if (request_headers.Host) {
|
||||||
|
if (minisrv_config.config.pc_server_hidden_service_enabled) {
|
||||||
|
// browsers typically send a Host header
|
||||||
|
service_name = minisrv_config.config.pc_server_hidden_service;
|
||||||
|
socket.minisrv_pc_mode = true;
|
||||||
|
shortURL = service_name + ":" + shortURL;
|
||||||
|
|
||||||
|
// if a directory, request index
|
||||||
|
if (shortURL.substring(shortURL.length - 1) == "/") shortURL += "index";
|
||||||
|
} else {
|
||||||
|
// minimal pc mode to send error
|
||||||
|
socket.minisrv_pc_mode = true;
|
||||||
|
var errpage = doErrorPage(401, "PC services are disabled on this server", socket.minisrv_pc_mode);
|
||||||
|
headers = errpage[0];
|
||||||
|
data = errpage[1]
|
||||||
|
socket_sessions[socket.id].close_me = true;
|
||||||
|
sendToClient(socket, headers, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// look up service name by socket port
|
||||||
|
service_name = getServiceBySocket(socket);
|
||||||
|
shortURL = service_name + ":" + shortURL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shortURL.indexOf(':/') >= 0 && shortURL.indexOf('://') < 0) {
|
if (shortURL.indexOf(':/') >= 0 && shortURL.indexOf('://') < 0) {
|
||||||
@@ -744,10 +830,10 @@ async function sendToClient(socket, headers_obj, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var end_of_line = "\n";
|
var end_of_line = "\n";
|
||||||
if (headers_obj['minisrv-use-carriage-return'] == "true") end_of_line = "\r\n";
|
if (socket.minisrv_pc_mode) {
|
||||||
if (headers_obj['minisrv-use-carriage-return']) delete headers_obj['minisrv-use-carriage-return'];
|
end_of_line = "\r\n";
|
||||||
|
headers_obj['http_response'] = "HTTP/1.0 " + headers_obj['http_response'];
|
||||||
if (end_of_line == "\r\n" && zdebug) console.log(" * Script requested to send headers with carriage return (out of WTVP Spec)");
|
}
|
||||||
|
|
||||||
// header object to string
|
// header object to string
|
||||||
if (zshowheaders) console.log(" * Outgoing headers on socket ID", socket.id, (await filterSSID(headers_obj)));
|
if (zshowheaders) console.log(" * Outgoing headers on socket ID", socket.id, (await filterSSID(headers_obj)));
|
||||||
@@ -1359,6 +1445,7 @@ async function handleSocket(socket) {
|
|||||||
// create unique socket id with client address and port
|
// create unique socket id with client address and port
|
||||||
socket.id = parseInt(crc16('CCITT-FALSE', Buffer.from(String(socket.remoteAddress) + String(socket.remotePort), "utf8")).toString(16), 16);
|
socket.id = parseInt(crc16('CCITT-FALSE', Buffer.from(String(socket.remoteAddress) + String(socket.remotePort), "utf8")).toString(16), 16);
|
||||||
socket_sessions[socket.id] = [];
|
socket_sessions[socket.id] = [];
|
||||||
|
socket.minisrv_pc_mode = false;
|
||||||
socket.setEncoding('hex'); //set data encoding (Text: 'ascii', 'utf8' ~ Binary: 'hex', 'base64' (do not trust 'binary' encoding))
|
socket.setEncoding('hex'); //set data encoding (Text: 'ascii', 'utf8' ~ Binary: 'hex', 'base64' (do not trust 'binary' encoding))
|
||||||
socket.setTimeout(10800000); // 3 hours
|
socket.setTimeout(10800000); // 3 hours
|
||||||
socket.on('data', function (data_hex) {
|
socket.on('data', function (data_hex) {
|
||||||
|
|||||||
@@ -14,8 +14,11 @@
|
|||||||
"post_percentages": [ 0, 25, 50, 100 ],
|
"post_percentages": [ 0, 25, 50, 100 ],
|
||||||
"verbosity": 2,
|
"verbosity": 2,
|
||||||
"error_log_file": "errors.log",
|
"error_log_file": "errors.log",
|
||||||
|
"catchall_file_name": "catchall.js",
|
||||||
"enable_lzpf_compression": false,
|
"enable_lzpf_compression": false,
|
||||||
"enable_gzip_compression": true,
|
"enable_gzip_compression": true,
|
||||||
|
"pc_server_hidden_service": "http_pc",
|
||||||
|
"pc_server_hidden_service_enabled": false,
|
||||||
"allow_guests": true
|
"allow_guests": true
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
@@ -53,7 +56,8 @@
|
|||||||
"flags": "0x00000040",
|
"flags": "0x00000040",
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"use_zefie_server": true,
|
"use_zefie_server": true,
|
||||||
"bf0app_default_rom": "content/artemis-webtv-000/build7181/daily-nondebug/bf0app-part000.rom"
|
"bf0app_default_rom": "content/artemis-webtv-000/build7181/daily-nondebug/bf0app-part000.rom",
|
||||||
|
"catchall_file_name": "content-serve.js"
|
||||||
},
|
},
|
||||||
"wtv-setup": {
|
"wtv-setup": {
|
||||||
"port": 1613,
|
"port": 1613,
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
<Content Include=".gitignore" />
|
<Content Include=".gitignore" />
|
||||||
<Content Include="app.js" />
|
<Content Include="app.js" />
|
||||||
<Content Include="config.json" />
|
<Content Include="config.json" />
|
||||||
|
<Content Include="ServiceVault\http_pc\get.js" />
|
||||||
|
<Content Include="ServiceVault\http_pc\index.js" />
|
||||||
<Content Include="ServiceVault\wtv-1800\noflash.js" />
|
<Content Include="ServiceVault\wtv-1800\noflash.js" />
|
||||||
<Content Include="ServiceVault\wtv-1800\offer-open-isp-suggest.js" />
|
<Content Include="ServiceVault\wtv-1800\offer-open-isp-suggest.js" />
|
||||||
<Content Include="ServiceVault\wtv-chat\home.js" />
|
<Content Include="ServiceVault\wtv-chat\home.js" />
|
||||||
@@ -50,6 +52,7 @@
|
|||||||
<Content Include="ServiceVault\wtv-cookie\reset.js">
|
<Content Include="ServiceVault\wtv-cookie\reset.js">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="ServiceVault\wtv-flashrom\content\content-serve.js" />
|
||||||
<Content Include="ServiceVault\wtv-flashrom\current-noflash.js">
|
<Content Include="ServiceVault\wtv-flashrom\current-noflash.js">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -289,10 +292,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="ServiceVault\" />
|
<Folder Include="ServiceVault\" />
|
||||||
|
<Folder Include="ServiceVault\http_pc\" />
|
||||||
<Folder Include="ServiceVault\wtv-chat\" />
|
<Folder Include="ServiceVault\wtv-chat\" />
|
||||||
<Folder Include="ServiceVault\wtv-chat\images\" />
|
<Folder Include="ServiceVault\wtv-chat\images\" />
|
||||||
<Folder Include="ServiceVault\wtv-cookie\" />
|
<Folder Include="ServiceVault\wtv-cookie\" />
|
||||||
<Folder Include="ServiceVault\wtv-flashrom\" />
|
<Folder Include="ServiceVault\wtv-flashrom\" />
|
||||||
|
<Folder Include="ServiceVault\wtv-flashrom\content\" />
|
||||||
<Folder Include="ServiceVault\wtv-flashrom\ROMCache\" />
|
<Folder Include="ServiceVault\wtv-flashrom\ROMCache\" />
|
||||||
<Folder Include="ServiceVault\wtv-music\" />
|
<Folder Include="ServiceVault\wtv-music\" />
|
||||||
<Folder Include="ServiceVault\wtv-music\demo\" />
|
<Folder Include="ServiceVault\wtv-music\demo\" />
|
||||||
|
|||||||
Reference in New Issue
Block a user