From 76549e72285e91666dfbe5e58ea7ce8663ec8e72 Mon Sep 17 00:00:00 2001 From: gnh1201 Date: Mon, 7 Dec 2020 17:33:12 +0900 Subject: [PATCH] fix --- app/assets/js/json2.js | 530 +++++++++++++++++++++++++++++++++++++++++ app/index.js | 4 +- lib/file.js | 22 +- lib/http.js | 68 ++++-- lib/updater.js | 79 ++++-- versionid.txt | 1 + 6 files changed, 662 insertions(+), 42 deletions(-) create mode 100644 app/assets/js/json2.js create mode 100644 versionid.txt diff --git a/app/assets/js/json2.js b/app/assets/js/json2.js new file mode 100644 index 0000000..f6fada6 --- /dev/null +++ b/app/assets/js/json2.js @@ -0,0 +1,530 @@ +// json2.js +// 2017-06-12 +// Public Domain. +// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + +// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO +// NOT CONTROL. + +// This file creates a global JSON object containing two methods: stringify +// and parse. This file provides the ES5 JSON capability to ES3 systems. +// If a project might run on IE8 or earlier, then this file should be included. +// This file does nothing on ES5 systems. + +// JSON.stringify(value, replacer, space) +// value any JavaScript value, usually an object or array. +// replacer an optional parameter that determines how object +// values are stringified for objects. It can be a +// function or an array of strings. +// space an optional parameter that specifies the indentation +// of nested structures. If it is omitted, the text will +// be packed without extra whitespace. If it is a number, +// it will specify the number of spaces to indent at each +// level. If it is a string (such as "\t" or " "), +// it contains the characters used to indent at each level. +// This method produces a JSON text from a JavaScript value. +// When an object value is found, if the object contains a toJSON +// method, its toJSON method will be called and the result will be +// stringified. A toJSON method does not serialize: it returns the +// value represented by the name/value pair that should be serialized, +// or undefined if nothing should be serialized. The toJSON method +// will be passed the key associated with the value, and this will be +// bound to the value. + +// For example, this would serialize Dates as ISO strings. + +// Date.prototype.toJSON = function (key) { +// function f(n) { +// // Format integers to have at least two digits. +// return (n < 10) +// ? "0" + n +// : n; +// } +// return this.getUTCFullYear() + "-" + +// f(this.getUTCMonth() + 1) + "-" + +// f(this.getUTCDate()) + "T" + +// f(this.getUTCHours()) + ":" + +// f(this.getUTCMinutes()) + ":" + +// f(this.getUTCSeconds()) + "Z"; +// }; + +// You can provide an optional replacer method. It will be passed the +// key and value of each member, with this bound to the containing +// object. The value that is returned from your method will be +// serialized. If your method returns undefined, then the member will +// be excluded from the serialization. + +// If the replacer parameter is an array of strings, then it will be +// used to select the members to be serialized. It filters the results +// such that only members with keys listed in the replacer array are +// stringified. + +// Values that do not have JSON representations, such as undefined or +// functions, will not be serialized. Such values in objects will be +// dropped; in arrays they will be replaced with null. You can use +// a replacer function to replace those with JSON values. + +// JSON.stringify(undefined) returns undefined. + +// The optional space parameter produces a stringification of the +// value that is filled with line breaks and indentation to make it +// easier to read. + +// If the space parameter is a non-empty string, then that string will +// be used for indentation. If the space parameter is a number, then +// the indentation will be that many spaces. + +// Example: + +// text = JSON.stringify(["e", {pluribus: "unum"}]); +// // text is '["e",{"pluribus":"unum"}]' + +// text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t"); +// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + +// text = JSON.stringify([new Date()], function (key, value) { +// return this[key] instanceof Date +// ? "Date(" + this[key] + ")" +// : value; +// }); +// // text is '["Date(---current time---)"]' + +// JSON.parse(text, reviver) +// This method parses a JSON text to produce an object or array. +// It can throw a SyntaxError exception. + +// The optional reviver parameter is a function that can filter and +// transform the results. It receives each of the keys and values, +// and its return value is used instead of the original value. +// If it returns what it received, then the structure is not modified. +// If it returns undefined then the member is deleted. + +// Example: + +// // Parse the text. Values that look like ISO date strings will +// // be converted to Date objects. + +// myData = JSON.parse(text, function (key, value) { +// var a; +// if (typeof value === "string") { +// a = +// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); +// if (a) { +// return new Date(Date.UTC( +// +a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6] +// )); +// } +// return value; +// } +// }); + +// myData = JSON.parse( +// "[\"Date(09/09/2001)\"]", +// function (key, value) { +// var d; +// if ( +// typeof value === "string" +// && value.slice(0, 5) === "Date(" +// && value.slice(-1) === ")" +// ) { +// d = new Date(value.slice(5, -1)); +// if (d) { +// return d; +// } +// } +// return value; +// } +// ); + +// This is a reference implementation. You are free to copy, modify, or +// redistribute. + +/*jslint + eval, for, this +*/ + +/*property + JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== "object") { + JSON = {}; +} + +(function () { + "use strict"; + + var rx_one = /^[\],:{}\s]*$/; + var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; + var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + var rx_four = /(?:^|:|,)(?:\s*\[)+/g; + var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + + function f(n) { + // Format integers to have at least two digits. + return (n < 10) + ? "0" + n + : n; + } + + function this_value() { + return this.valueOf(); + } + + if (typeof Date.prototype.toJSON !== "function") { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? ( + this.getUTCFullYear() + + "-" + + f(this.getUTCMonth() + 1) + + "-" + + f(this.getUTCDate()) + + "T" + + f(this.getUTCHours()) + + ":" + + f(this.getUTCMinutes()) + + ":" + + f(this.getUTCSeconds()) + + "Z" + ) + : null; + }; + + Boolean.prototype.toJSON = this_value; + Number.prototype.toJSON = this_value; + String.prototype.toJSON = this_value; + } + + var gap; + var indent; + var meta; + var rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + rx_escapable.lastIndex = 0; + return rx_escapable.test(string) + ? "\"" + string.replace(rx_escapable, function (a) { + var c = meta[a]; + return typeof c === "string" + ? c + : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4); + }) + "\"" + : "\"" + string + "\""; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i; // The loop counter. + var k; // The member key. + var v; // The member value. + var length; + var mind = gap; + var partial; + var value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if ( + value + && typeof value === "object" + && typeof value.toJSON === "function" + ) { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === "function") { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case "string": + return quote(value); + + case "number": + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return (isFinite(value)) + ? String(value) + : "null"; + + case "boolean": + case "null": + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce "null". The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is "object", we might be dealing with an object or an array or +// null. + + case "object": + +// Due to a specification blunder in ECMAScript, typeof null is "object", +// so watch out for that case. + + if (!value) { + return "null"; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === "[object Array]") { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || "null"; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? "[]" + : gap + ? ( + "[\n" + + gap + + partial.join(",\n" + gap) + + "\n" + + mind + + "]" + ) + : "[" + partial.join(",") + "]"; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === "object") { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === "string") { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + ( + (gap) + ? ": " + : ":" + ) + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + ( + (gap) + ? ": " + : ":" + ) + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? "{}" + : gap + ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" + : "{" + partial.join(",") + "}"; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== "function") { + meta = { // table of character substitutions + "\b": "\\b", + "\t": "\\t", + "\n": "\\n", + "\f": "\\f", + "\r": "\\r", + "\"": "\\\"", + "\\": "\\\\" + }; + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ""; + indent = ""; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === "number") { + for (i = 0; i < space; i += 1) { + indent += " "; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === "string") { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== "function" && ( + typeof replacer !== "object" + || typeof replacer.length !== "number" + )) { + throw new Error("JSON.stringify"); + } + +// Make a fake root object containing our value under the key of "". +// Return the result of stringifying the value. + + return str("", {"": value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== "function") { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k; + var v; + var value = holder[key]; + if (value && typeof value === "object") { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + rx_dangerous.lastIndex = 0; + if (rx_dangerous.test(text)) { + text = text.replace(rx_dangerous, function (a) { + return ( + "\\u" + + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) + ); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with "()" and "new" +// because they can cause invocation, and "=" because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we +// replace all simple value tokens with "]" characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or "]" or +// "," or ":" or "{" or "}". If that is so, then the text is safe for eval. + + if ( + rx_one.test( + text + .replace(rx_two, "@") + .replace(rx_three, "]") + .replace(rx_four, "") + ) + ) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The "{" operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval("(" + text + ")"); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return (typeof reviver === "function") + ? walk({"": j}, "") + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError("JSON.parse"); + }; + } +}()); diff --git a/app/index.js b/app/index.js index 54d2d2d..a6c40e0 100644 --- a/app/index.js +++ b/app/index.js @@ -42,10 +42,10 @@ var getLocalApplications = function() { for (var i = 0; i < NoxPList.length; i++) { localApplications.push({ name: "NoxPlayer", - uniqueId: NoxPList[i].hostname + uniqueId: NoxPList[i].title }); } - + // Chrome /* localApplications.push({ diff --git a/lib/file.js b/lib/file.js index 2d37695..29c9832 100644 --- a/lib/file.js +++ b/lib/file.js @@ -49,7 +49,6 @@ exports.fileGet = function(FN) { FSO = null; return file; }; - ///////////////////////////////////////////////////////////////////////////////// // exports.readFile // Read the conents of the pass filename and return as a string @@ -134,6 +133,17 @@ exports.writeFile = function(FN, content, charset) { return ok; }; +exports.writeBinaryFile = function(FN, DATA) { + var adTypeText = 1; + var adSaveCreateOverWrite = 2; + var BinaryStream = CreateObject("ADODB.Stream"); + BinaryStream.Type = adTypeText; + BinaryStream.Open(); + BinaryStream.Write(DATA); + BinaryStream.SaveToFile(FN, adSaveCreateOverWrite); + BinaryStream.Close(); +}; + ///////////////////////////////////////////////////////////////////////////////// // exports.moveFile ///////////////////////////////////////////////////////////////////////////////// @@ -167,4 +177,12 @@ exports.deleteFile = function(FN) { return res; }; -///////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +///////////////////////////////////////////////////////////////////////////////// + +exports.includeFile = function(FN) { + var fso = CreateObject("Scripting.FileSystemObject"); + var fileStream = fso.openTextFile(FN); + var fileData = fileStream.readAll(); + fileStream.Close(); + eval(fileData); +}; diff --git a/lib/http.js b/lib/http.js index 846f9eb..e699e29 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1,6 +1,7 @@ //////////////////////////////////////////////////////////////////////// // HTTP API //////////////////////////////////////////////////////////////////////// +var FILE = require("lib/file"); var HTTPObject = function() { this.interface = null; @@ -48,18 +49,22 @@ var HTTPObject = function() { }; this.isJSONResponse = function() { - if (this.dataType === "json") { - return true; - } else { - var headers = this.getHeaders(); - for (var key in headers) { - var _k = key.toLowerCase(); - var _v = headers[key].toLowerCase(); - if (_k === "content-type" && _v === "application/json") { - this.dataType = "json"; - return true; + try { + if (this.dataType === "json") { + return true; + } else { + var headers = this.getHeaders(); + for (var key in headers) { + var _k = key.toLowerCase(); + var _v = headers[key].toLowerCase(); + if (_k === "content-type" && _v === "application/json") { + this.dataType = "json"; + return true; + } } } + } catch (e) { + console.error("HTTPObject.isJSONResponse() -> ", e.message); } return false; @@ -95,13 +100,17 @@ var HTTPObject = function() { }; this.setHeaders = function(headers) { - var headers = (typeof(headers) !== "undefined") ? headers : {}; - for (var key in headers) { - var value = headers[key]; - this.setHeader(key, value); - if (key.toLowerCase() == "content-type") { - this.contentType = value.toLowerCase(); + try { + var headers = (typeof(headers) !== "undefined") ? headers : {}; + for (var key in headers) { + var value = headers[key]; + this.setHeader(key, value); + if (key.toLowerCase() == "content-type") { + this.contentType = value.toLowerCase(); + } } + } catch (e) { + console.error("HTTPObject.setHeaders() -> ", e.message); } return this; @@ -142,10 +151,14 @@ var HTTPObject = function() { }; this.setParameters = function(params) { - var params = (typeof(params) !== "undefined") ? params : {}; - for (var key in params) { - var value = params[key]; - this.setParameter(key, value); + try { + var params = (typeof(params) !== "undefined") ? params : {}; + for (var key in params) { + var value = params[key]; + this.setParameter(key, value); + } + } catch (e) { + console.error("HTTPObject.setParameters() -> ", e.message); } return this; }; @@ -254,20 +267,27 @@ var HTTPObject = function() { this.interface.send(this.serialize(this.requestBody)); } + // Waiting a response while (this.interface.readyState < 4) { - console.debug("Waiting a response..."); - sleep(1000); + sleep(100); } - console.debug(this.interface.responseText); if (this.isJSONResponse()) { + if (typeof(WScript) !== "undefined") { + JSON = {}; + FILE.includeFile("app/assets/js/json2.js"); + } this.setResponseBody(JSON.parse(this.interface.responseText)); } else { this.setResponseBody(this.interface.responseText); } if (typeof(callback) === "function") { - callback(this.responseBody); + try { + callback(this.responseBody); + } catch (e) { + console.log("callback of HTTPObject.send() -> ", e.message); + } } } catch (e) { console.error("HTTPObject.send() -> ", e.message); diff --git a/lib/updater.js b/lib/updater.js index bd5316a..ad6abf9 100644 --- a/lib/updater.js +++ b/lib/updater.js @@ -1,25 +1,76 @@ var FILE = require("lib/file"); var HTTP = require("lib/http"); var CONFIG = require("lib/config"); +var SHELL = require("lib/shell"); -exports.checkUpdates = function() { - var token = FILE.readFile("token.txt", "utf-8"); - var apiUrl = CONFIG.getValue("ApiUrl"); +var apiUrl = CONFIG.getValue("ApiUrl"); +var token = null; +var versionId = 0; + +if (FILE.fileExists("token.txt")) { + token = FILE.readFile("token.txt", "utf-8"); +} + +if (FILE.fileExists("versionid.txt")) { + versionId = parseInt(FILE.readFile("versionid.txt", "utf-8")); +} + +var downloadFile = function(url) { + // download a file + console.log(SHELL.exec(["bin\\curl", url, "-o", "update.zip"])); + + // extract a file + console.log(SHELL.exec(["bin\\unzip", "-o", "update.zip"])); + + // run installer + SHELL.run(["start", "mysetup.exe"]); + + // close window + exit(); +}; + +var requestFile = function(id) { var onSuccess = function(res) { var data = res.data; - for (var i = 0; i < data.length; i++) { - console.log("UPDATE ID: ", data.file); - } - } + var full_url = data.data.full_url; + console.log("Downloading a file..."); + downloadFile(full_url); + }; + + console.log("Requesting a file..."); HTTP.create() .setContentType("application/x-www-form-urlencoded") .setBearerAuth(token) - .setParameters({ - "status": "published", - "sort": "-created_on", - "limit": 1 - }) - .get(apiUrl + "/netsolid/items/updates", onSuccess) + .get(apiUrl + "/netsolid/files/" + id, onSuccess) ; -}; \ No newline at end of file +}; + +var checkUpdates = function() { + if (!token) { + console.warn("Could not find authorization token. 로그인이 필요합니다."); + } else { + var onSuccess = function(res) { + var data = res.data; + for (var i = 0; i < data.length; i++) { + if (data[i].id > versionId) { + console.info("업데이트가 있습니다. 다운로드를 진행합니다."); + requestFile(data[i].file); + } + } + }; + + HTTP.create() + .setContentType("application/x-www-form-urlencoded") + .setBearerAuth(token) + .setParameters({ + "status": "published", + "sort": "-created_on", + "limit": 1 + }) + .get(apiUrl + "/netsolid/items/updates", onSuccess) + ; + } +}; + +exports.checkUpdates = checkUpdates; diff --git a/versionid.txt b/versionid.txt new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/versionid.txt @@ -0,0 +1 @@ +1 \ No newline at end of file