🚀 Add TypeScript code
This commit is contained in:
parent
59f6ae0f11
commit
89faa530ec
17 changed files with 368 additions and 8 deletions
|
@ -7,3 +7,6 @@ charset = utf-8
|
|||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
|
||||
[*.php]
|
||||
indent_size = 4
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
|||
.vscode
|
||||
!.vscode/settings.json
|
||||
dist
|
||||
node_modules
|
||||
dbSettings.js
|
||||
|
|
15
README.md
15
README.md
|
@ -1,6 +1,19 @@
|
|||
# ssn-auto
|
||||
|
||||
A tool that regularly checks for new patches and will automatically download, install and process them. Designed to be deployed on the Jedipedia server and may be difficult to set up in other environments. If you want to build your own patching tool, start with the [ssn-tools](/swtor/ssn-tools) repository.
|
||||
A tool that regularly checks for new patches and will automatically download, install and process them. Designed to be deployed on the Jedipedia server and not supported to be set up in other environments, so we offer limited support. If you want to build your own patching tool, start with the [ssn-tools](/swtor/ssn-tools) repository.
|
||||
|
||||
## Installation
|
||||
|
||||
After downloading this repository, create a file called `dbSettings.js` with the following contents, putting in the database settings as required:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
user: 'INSERT_USER_NAME',
|
||||
password: 'INSERT_PASSWORD',
|
||||
database: 'INSERT_DATABASE_NAME',
|
||||
};
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
|
|
4
dbSettings.d.ts
vendored
Normal file
4
dbSettings.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
export const host: string;
|
||||
export const user: string;
|
||||
export const password: string;
|
||||
export const database: string;
|
117
package-lock.json
generated
117
package-lock.json
generated
|
@ -1,4 +1,119 @@
|
|||
{
|
||||
"name": "ssn-auto",
|
||||
"lockfileVersion": 1
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@types/mysql": {
|
||||
"version": "2.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.5.tgz",
|
||||
"integrity": "sha512-4QAISTUGZbcFh7bqdndo08xRdES5OTU+JODy8VCZbe1yiXyGjqw1H83G43XjQ3IbC10wn9xlGd44A5RXJwNh0Q==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.12.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.2.tgz",
|
||||
"integrity": "sha512-53ElVDSnZeFUUFIYzI8WLQ25IhWzb6vbddNp8UHlXQyU0ET2RhV5zg0NfubzU7iNMh5bBXb0htCzfvrSVNgzaQ=="
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
|
||||
"integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA=="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"mysql": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz",
|
||||
"integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==",
|
||||
"requires": {
|
||||
"bignumber.js": "4.1.0",
|
||||
"readable-stream": "2.3.6",
|
||||
"safe-buffer": "5.1.2",
|
||||
"sqlstring": "2.3.1"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"sqlstring": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
|
||||
"integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A="
|
||||
},
|
||||
"ssn": {
|
||||
"version": "git+https://git.jedipedia.net/swtor/ssn.git#5caa3a935d8a1dda040fbe2f7d63114213b01e81",
|
||||
"from": "git+https://git.jedipedia.net/swtor/ssn.git",
|
||||
"requires": {
|
||||
"@types/node": "^10.12.2",
|
||||
"ssn-installer": "git+https://git.jedipedia.net/swtor/ssn-installer.git#488e49b6b234caca0bfbc3f746fa16abdc002dea",
|
||||
"xml-js": "^1.6.8"
|
||||
}
|
||||
},
|
||||
"ssn-installer": {
|
||||
"version": "git+https://git.jedipedia.net/swtor/ssn-installer.git#488e49b6b234caca0bfbc3f746fa16abdc002dea",
|
||||
"from": "git+https://git.jedipedia.net/swtor/ssn-installer.git"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"xml-js": {
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.8.tgz",
|
||||
"integrity": "sha512-kUv/geyN80d+s1T68uBfjoz+PjNUjwwf5AWWRwKRqqQaGozpMVsFsKYnenPsxlbN/VL7f0ia8NfLLPCDwX+95Q==",
|
||||
"requires": {
|
||||
"sax": "^1.2.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
package.json
13
package.json
|
@ -6,9 +6,16 @@
|
|||
"type": "git",
|
||||
"url": "https://git.jedipedia.net/swtor/ssn-auto.git"
|
||||
},
|
||||
"main": "src/index.php",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"start": "rm -rf dist && tsc",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"update": "rm -rf node_modules package-lock.json && npm install"
|
||||
},
|
||||
"dependencies": {}
|
||||
"dependencies": {
|
||||
"@types/mysql": "^2.15.5",
|
||||
"mysql": "^2.16.0",
|
||||
"ssn": "git+https://git.jedipedia.net/swtor/ssn.git"
|
||||
}
|
||||
}
|
||||
|
|
28
src/getConfig.ts
Normal file
28
src/getConfig.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { Product } from 'ssn';
|
||||
import IProductData from './interfaces/IProductData';
|
||||
|
||||
const data: { [key in Product]: IProductData } = {
|
||||
assets_swtor_main: { manifestVersion: 294, httpVersion: 294 },
|
||||
assets_swtor_de_de: { manifestVersion: 297, httpVersion: 297 },
|
||||
assets_swtor_en_us: { manifestVersion: 299, httpVersion: 299 },
|
||||
assets_swtor_fr_fr: { manifestVersion: 299, httpVersion: 299 },
|
||||
assets_swtor_test_main: { manifestVersion: 292, httpVersion: 292 },
|
||||
assets_swtor_test_de_de: { manifestVersion: 295, httpVersion: 295 },
|
||||
assets_swtor_test_en_us: { manifestVersion: 295, httpVersion: 295 },
|
||||
assets_swtor_test_fr_fr: { manifestVersion: 295, httpVersion: 295 },
|
||||
retailclient_swtor: { manifestVersion: 247, httpVersion: 247 },
|
||||
retailclient_publictest: { manifestVersion: 269, httpVersion: 269 },
|
||||
retailclient_betatest: { manifestVersion: 13, httpVersion: 13 },
|
||||
retailclient_liveqatest: { manifestVersion: 203, httpVersion: 205 },
|
||||
retailclient_liveeptest: { manifestVersion: 133, httpVersion: 199 },
|
||||
retailclient_cstraining: { manifestVersion: 141, httpVersion: 141 },
|
||||
retailclient_squadron157: { manifestVersion: 11, httpVersion: -1 },
|
||||
eualas: { manifestVersion: 0, httpVersion: 0 },
|
||||
patcher2014: { manifestVersion: 8, httpVersion: 7 },
|
||||
patcher2017: { manifestVersion: 0, httpVersion: 0 },
|
||||
movies_de_de: { manifestVersion: 5, httpVersion: 5 },
|
||||
movies_en_us: { manifestVersion: 5, httpVersion: 5 },
|
||||
movies_fr_fr: { manifestVersion: 5, httpVersion: 5 },
|
||||
};
|
||||
|
||||
export default data;
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
echo 'Hello World!';
|
37
src/index.ts
Normal file
37
src/index.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { getSolidpkg, Product } from 'ssn';
|
||||
import products from './getConfig';
|
||||
import IProductData from './interfaces/IProductData';
|
||||
import * as model from './model/model';
|
||||
import * as database from './model/database';
|
||||
|
||||
//create lock file to prevent conflicts?
|
||||
|
||||
const newPatches: any[] = [];
|
||||
|
||||
model.init().then(() => {
|
||||
database.exit();
|
||||
});
|
||||
|
||||
/*//for each product, check new versions
|
||||
Object.entries(products).forEach(([product, { manifestVersion, httpVersion }]: [string, IProductData]) => {
|
||||
const curVersion = 100;
|
||||
//Check patch to next release
|
||||
for (let i = curVersion; i < curVersion + 3; i += 1) {
|
||||
getSolidpkg(product as Product, i, i + 1).then((result) => {
|
||||
console.log(result);
|
||||
newPatches.push({ product, version: i, result });
|
||||
}).catch(() => {
|
||||
//do nothing
|
||||
});
|
||||
}
|
||||
//TODO
|
||||
});*/
|
||||
|
||||
//parse results
|
||||
//TODO: need to wait for all promises to be complete
|
||||
|
||||
//if new version was found, try to install it
|
||||
|
||||
//also check manifest in case a new version is available for installation. remember time when patch became available for installation but otherwise do nothing
|
||||
|
||||
//delete lock file
|
6
src/interfaces/IProductData.ts
Normal file
6
src/interfaces/IProductData.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default interface IProductData {
|
||||
/** Latest release number of this product according to manifest. */
|
||||
manifestVersion: number;
|
||||
/** Latest release number of this product available from the patch server. */
|
||||
httpVersion: number;
|
||||
}
|
3
src/logger/writeLog.ts
Normal file
3
src/logger/writeLog.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function writeLog(message: string, severity: number = 0) {
|
||||
console.warn(message);
|
||||
}
|
9
src/model/createStatement.ts
Normal file
9
src/model/createStatement.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
//Generated by `SHOW CREATE TABLE ssn_versions`
|
||||
const createStatement = `CREATE TABLE \`ssn_versions\` (
|
||||
\`product\` tinytext COLLATE utf8mb4_unicode_520_ci NOT NULL,
|
||||
\`manifest\` smallint(6) NOT NULL DEFAULT '-1',
|
||||
\`http\` smallint(6) NOT NULL DEFAULT '-1',
|
||||
PRIMARY KEY (\`product\`(25))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci`;
|
||||
|
||||
export default createStatement;
|
30
src/model/database.ts
Normal file
30
src/model/database.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import * as mysql from 'mysql';
|
||||
import * as dbSettings from '../../dbSettings';
|
||||
|
||||
const connection = mysql.createConnection(dbSettings);
|
||||
|
||||
export function init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.connect(function(err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function query(command: string): Promise<{ results: any, fields?: mysql.FieldInfo[] }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.query(command, function(error, results, fields) {
|
||||
if (error !== null) {
|
||||
reject(error);
|
||||
}
|
||||
resolve({ results, fields });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function exit(): void {
|
||||
connection.end();
|
||||
}
|
39
src/model/model.ts
Normal file
39
src/model/model.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { Product } from 'ssn';
|
||||
import * as database from './database';
|
||||
import products from './products';
|
||||
import writeLog from '../logger/writeLog';
|
||||
import createStatement from './createStatement';
|
||||
|
||||
export async function init() {
|
||||
await database.init();
|
||||
|
||||
//Only create table if it does not exist yet
|
||||
const createIfNotExists = createStatement.replace(/^CREATE TABLE/, 'CREATE TABLE IF NOT EXISTS');
|
||||
await database.query(createIfNotExists);
|
||||
|
||||
/**Products that are missing from the database and need to be inserted. */
|
||||
const missingProducts: Product[] = [];
|
||||
/** Products inside the database table that are not valid products. Will be printed to error log and ignored */
|
||||
const erroneousProducts: Product[] = [];
|
||||
|
||||
const { results: existingRows } = await database.query('SELECT * FROM ssn_versions');
|
||||
console.log(existingRows);
|
||||
return;
|
||||
|
||||
existingRows.forEach((row: any) => {
|
||||
//TODO: match with products
|
||||
});
|
||||
|
||||
//If row does not exist, INSERT into table
|
||||
await Promise.all(missingProducts.map((product) => {
|
||||
return database.query(`INSERT INTO ssn_versions ${product}`);
|
||||
}));
|
||||
|
||||
//If row exists that is not in products, ignore it and output error
|
||||
erroneousProducts.forEach((product) => {
|
||||
writeLog(`Product ${product} in database table is invalid.`);
|
||||
});
|
||||
|
||||
//TODO: insert products
|
||||
|
||||
}
|
27
src/model/products.ts
Normal file
27
src/model/products.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { Product } from 'ssn';
|
||||
|
||||
const productList: Product[] = [
|
||||
'assets_swtor_de_de',
|
||||
'assets_swtor_en_us',
|
||||
'assets_swtor_fr_fr',
|
||||
'assets_swtor_main',
|
||||
'assets_swtor_test_de_de',
|
||||
'assets_swtor_test_en_us',
|
||||
'assets_swtor_test_fr_fr',
|
||||
'assets_swtor_test_main',
|
||||
'eualas',
|
||||
'movies_de_de',
|
||||
'movies_en_us',
|
||||
'movies_fr_fr',
|
||||
'patcher2014',
|
||||
'patcher2017',
|
||||
'retailclient_betatest',
|
||||
'retailclient_cstraining',
|
||||
'retailclient_liveeptest',
|
||||
'retailclient_liveqatest',
|
||||
'retailclient_publictest',
|
||||
'retailclient_squadron157',
|
||||
'retailclient_swtor',
|
||||
];
|
||||
|
||||
export default productList;
|
18
src/tslint.json
Normal file
18
src/tslint.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended",
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"comment-format": false,
|
||||
"indent": [true, "spaces", 2],
|
||||
"max-line-length": false,
|
||||
"no-bitwise": false,
|
||||
"no-console": false,
|
||||
"no-invalid-this": [true, "check-function-in-method"],
|
||||
"object-literal-sort-keys": [true, "match-declaration-order"],
|
||||
"quotemark": [true, "single"],
|
||||
},
|
||||
"rulesDirectory": [],
|
||||
}
|
22
tsconfig.json
Normal file
22
tsconfig.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"declaration": true,
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"newLine": "lf",
|
||||
"outDir": "dist",
|
||||
"paths": {
|
||||
"*": [
|
||||
"node_modules/*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"target": "es2018",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue