mirror of
https://github.com/Auties00/Reboot-Launcher.git
synced 2026-01-13 03:02:22 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00802ac6da | ||
|
|
1d68469297 | ||
|
|
83878db8c5 | ||
|
|
e3b8d7d182 | ||
|
|
45b8629207 | ||
|
|
2df1b81485 | ||
|
|
018ccb7f8e | ||
|
|
0d64251623 | ||
|
|
47adb572ea | ||
|
|
e3a42d6b81 | ||
|
|
e24f4e97b3 |
4
backend/README.md
Normal file
4
backend/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Backend
|
||||||
|
Fork of LawinV1
|
||||||
|
Awaiting rewrite in Dart
|
||||||
|
Use build.bat to generate the executable
|
||||||
@@ -4,6 +4,16 @@ const fs = require("fs");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const cookieParser = require("cookie-parser");
|
const cookieParser = require("cookie-parser");
|
||||||
|
|
||||||
|
const audit = require('express-requests-logger')
|
||||||
|
express.use(audit({
|
||||||
|
request: {
|
||||||
|
maxBodyLength: 150
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
maxBodyLength: 150
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
express.use(Express.json());
|
express.use(Express.json());
|
||||||
express.use(Express.urlencoded({ extended: true }));
|
express.use(Express.urlencoded({ extended: true }));
|
||||||
express.use(Express.static('public'));
|
express.use(Express.static('public'));
|
||||||
0
backend/install_packages.bat
Normal file
0
backend/install_packages.bat
Normal file
248
lawin/package-lock.json → backend/package-lock.json
generated
248
lawin/package-lock.json → backend/package-lock.json
generated
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"express-requests-logger": "^4.0.0",
|
||||||
"ini": "^2.0.0",
|
"ini": "^2.0.0",
|
||||||
"nexe": "^4.0.0-rc.6",
|
"nexe": "^4.0.0-rc.6",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
@@ -388,6 +389,23 @@
|
|||||||
"node": ">v0.4.12"
|
"node": ">v0.4.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bunyan": {
|
||||||
|
"version": "1.8.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz",
|
||||||
|
"integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==",
|
||||||
|
"engines": [
|
||||||
|
"node >=0.10.0"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"bunyan": "bin/bunyan"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"dtrace-provider": "~0.8",
|
||||||
|
"moment": "^2.19.3",
|
||||||
|
"mv": "~2",
|
||||||
|
"safe-json-stringify": "~1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@@ -1063,6 +1081,19 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dtrace-provider": {
|
||||||
|
"version": "0.8.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz",
|
||||||
|
"integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"nan": "^2.14.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/duplexer3": {
|
"node_modules/duplexer3": {
|
||||||
"version": "0.1.5",
|
"version": "0.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
|
||||||
@@ -1168,6 +1199,16 @@
|
|||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express-requests-logger": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-requests-logger/-/express-requests-logger-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-NHQptnDY0fceiTSWLnW0dbJSFlrvbFpCGHmY6LsTMmJLgkyO3x8qAJ+EsryQRMga20YH8Ynt/vnmg23QP07h1Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"bunyan": "^1.8.14",
|
||||||
|
"flat": "^5.0.2",
|
||||||
|
"lodash": "^4.17.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/express/node_modules/cookie": {
|
"node_modules/express/node_modules/cookie": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||||
@@ -1292,6 +1333,14 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/flat": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
||||||
|
"bin": {
|
||||||
|
"flat": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fn.name": {
|
"node_modules/fn.name": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||||
@@ -1788,6 +1837,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
||||||
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
"node_modules/log-symbols": {
|
"node_modules/log-symbols": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
|
||||||
@@ -1973,6 +2027,15 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/moo-server": {
|
"node_modules/moo-server": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz",
|
||||||
@@ -2009,6 +2072,77 @@
|
|||||||
"readable-stream": "^3.6.0"
|
"readable-stream": "^3.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mv": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"mkdirp": "~0.5.1",
|
||||||
|
"ncp": "~2.0.0",
|
||||||
|
"rimraf": "~2.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mv/node_modules/glob": {
|
||||||
|
"version": "6.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
|
||||||
|
"integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==",
|
||||||
|
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "2 || 3",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mv/node_modules/mkdirp": {
|
||||||
|
"version": "0.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||||
|
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": "^1.2.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"mkdirp": "bin/cmd.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mv/node_modules/rimraf": {
|
||||||
|
"version": "2.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
|
||||||
|
"integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==",
|
||||||
|
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"glob": "^6.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"rimraf": "bin.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nan": {
|
||||||
|
"version": "2.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz",
|
||||||
|
"integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"node_modules/ncp": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
|
||||||
|
"optional": true,
|
||||||
|
"bin": {
|
||||||
|
"ncp": "bin/ncp"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/negotiator": {
|
"node_modules/negotiator": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
@@ -2534,6 +2668,12 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/safe-json-stringify": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/safe-stable-stringify": {
|
"node_modules/safe-stable-stringify": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
|
||||||
@@ -3405,6 +3545,17 @@
|
|||||||
"wrench": "1.3.x"
|
"wrench": "1.3.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bunyan": {
|
||||||
|
"version": "1.8.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz",
|
||||||
|
"integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==",
|
||||||
|
"requires": {
|
||||||
|
"dtrace-provider": "~0.8",
|
||||||
|
"moment": "^2.19.3",
|
||||||
|
"mv": "~2",
|
||||||
|
"safe-json-stringify": "~1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@@ -3941,6 +4092,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dtrace-provider": {
|
||||||
|
"version": "0.8.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz",
|
||||||
|
"integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"nan": "^2.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"duplexer3": {
|
"duplexer3": {
|
||||||
"version": "0.1.5",
|
"version": "0.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
|
||||||
@@ -4038,6 +4198,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"express-requests-logger": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-requests-logger/-/express-requests-logger-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-NHQptnDY0fceiTSWLnW0dbJSFlrvbFpCGHmY6LsTMmJLgkyO3x8qAJ+EsryQRMga20YH8Ynt/vnmg23QP07h1Q==",
|
||||||
|
"requires": {
|
||||||
|
"bunyan": "^1.8.14",
|
||||||
|
"flat": "^5.0.2",
|
||||||
|
"lodash": "^4.17.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ext-list": {
|
"ext-list": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
|
||||||
@@ -4130,6 +4300,11 @@
|
|||||||
"unpipe": "~1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flat": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="
|
||||||
|
},
|
||||||
"fn.name": {
|
"fn.name": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||||
@@ -4496,6 +4671,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
||||||
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
||||||
},
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
"log-symbols": {
|
"log-symbols": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
|
||||||
@@ -4626,6 +4806,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"moo-server": {
|
"moo-server": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz",
|
||||||
@@ -4645,6 +4831,62 @@
|
|||||||
"readable-stream": "^3.6.0"
|
"readable-stream": "^3.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mv": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"mkdirp": "~0.5.1",
|
||||||
|
"ncp": "~2.0.0",
|
||||||
|
"rimraf": "~2.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"glob": {
|
||||||
|
"version": "6.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
|
||||||
|
"integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "2 || 3",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||||
|
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rimraf": {
|
||||||
|
"version": "2.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
|
||||||
|
"integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"glob": "^6.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.20.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz",
|
||||||
|
"integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"ncp": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"negotiator": {
|
"negotiator": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
@@ -5000,6 +5242,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
},
|
},
|
||||||
|
"safe-json-stringify": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"safe-stable-stringify": {
|
"safe-stable-stringify": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"ws": "^8.5.0",
|
"ws": "^8.5.0",
|
||||||
"xml-parser": "^1.2.1",
|
"xml-parser": "^1.2.1",
|
||||||
"xmlbuilder": "^15.1.1"
|
"xmlbuilder": "^15.1.1",
|
||||||
|
"express-requests-logger": "^4.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node index.js",
|
"start": "node index.js",
|
||||||
File diff suppressed because it is too large
Load Diff
0
backend/public/images/discord-s.png
Normal file
0
backend/public/images/discord-s.png
Normal file
0
backend/public/images/discord.png
Normal file
0
backend/public/images/discord.png
Normal file
0
backend/public/images/lawin-s.png
Normal file
0
backend/public/images/lawin-s.png
Normal file
0
backend/public/images/lawin.jpg
Normal file
0
backend/public/images/lawin.jpg
Normal file
0
backend/public/images/motd-s.png
Normal file
0
backend/public/images/motd-s.png
Normal file
0
backend/public/images/motd.png
Normal file
0
backend/public/images/motd.png
Normal file
0
backend/public/images/seasonx.png
Normal file
0
backend/public/images/seasonx.png
Normal file
0
backend/responses/CloudDir/LawinServer.chunk
Normal file
0
backend/responses/CloudDir/LawinServer.chunk
Normal file
0
backend/responses/CloudDir/LawinServer.manifest
Normal file
0
backend/responses/CloudDir/LawinServer.manifest
Normal file
@@ -75,5 +75,12 @@
|
|||||||
"direction": "OUTBOUND",
|
"direction": "OUTBOUND",
|
||||||
"created": "2024-05-31T19:50:04.738Z",
|
"created": "2024-05-31T19:50:04.738Z",
|
||||||
"favorite": false
|
"favorite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accountId": "Player724",
|
||||||
|
"status": "ACCEPTED",
|
||||||
|
"direction": "OUTBOUND",
|
||||||
|
"created": "2024-06-24T20:15:48.062Z",
|
||||||
|
"favorite": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -98,6 +98,15 @@
|
|||||||
"note": "",
|
"note": "",
|
||||||
"favorite": false,
|
"favorite": false,
|
||||||
"created": "2024-05-31T19:50:04.738Z"
|
"created": "2024-05-31T19:50:04.738Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accountId": "Player724",
|
||||||
|
"groups": [],
|
||||||
|
"mutual": 0,
|
||||||
|
"alias": "",
|
||||||
|
"note": "",
|
||||||
|
"favorite": false,
|
||||||
|
"created": "2024-06-24T20:15:48.062Z"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"incoming": [],
|
"incoming": [],
|
||||||
@@ -51,7 +51,7 @@ void main(List<String> args) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stdout.writeln("Launching game...");
|
stdout.writeln("Launching game...");
|
||||||
var executable = version.gameExecutable;
|
var executable = version.shippingExecutable;
|
||||||
if(executable == null){
|
if(executable == null){
|
||||||
throw Exception("Missing game executable at: ${version.location.path}");
|
throw Exception("Missing game executable at: ${version.location.path}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Future<void> startGame() async {
|
|||||||
await _startLauncherProcess(version);
|
await _startLauncherProcess(version);
|
||||||
await _startEacProcess(version);
|
await _startEacProcess(version);
|
||||||
|
|
||||||
var executable = await version.gameExecutable;
|
var executable = await version.shippingExecutable;
|
||||||
if (executable == null) {
|
if (executable == null) {
|
||||||
throw Exception("${version.location.path} no longer contains a Fortnite executable, did you delete or move it?");
|
throw Exception("${version.location.path} no longer contains a Fortnite executable, did you delete or move it?");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export 'package:reboot_common/src/model/server_result.dart';
|
|||||||
export 'package:reboot_common/src/model/server_type.dart';
|
export 'package:reboot_common/src/model/server_type.dart';
|
||||||
export 'package:reboot_common/src/model/update_status.dart';
|
export 'package:reboot_common/src/model/update_status.dart';
|
||||||
export 'package:reboot_common/src/model/update_timer.dart';
|
export 'package:reboot_common/src/model/update_timer.dart';
|
||||||
|
export 'package:reboot_common/src/model/fortnite_server.dart';
|
||||||
export 'package:reboot_common/src/model/dll.dart';
|
export 'package:reboot_common/src/model/dll.dart';
|
||||||
export 'package:reboot_common/src/util/backend.dart';
|
export 'package:reboot_common/src/util/backend.dart';
|
||||||
export 'package:reboot_common/src/util/build.dart';
|
export 'package:reboot_common/src/util/build.dart';
|
||||||
@@ -17,4 +18,5 @@ export 'package:reboot_common/src/util/dll.dart';
|
|||||||
export 'package:reboot_common/src/util/network.dart';
|
export 'package:reboot_common/src/util/network.dart';
|
||||||
export 'package:reboot_common/src/util/patcher.dart';
|
export 'package:reboot_common/src/util/patcher.dart';
|
||||||
export 'package:reboot_common/src/util/path.dart';
|
export 'package:reboot_common/src/util/path.dart';
|
||||||
export 'package:reboot_common/src/util/process.dart';
|
export 'package:reboot_common/src/util/process.dart';
|
||||||
|
export 'package:reboot_common/src/util/log.dart';
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
const String kDefaultBackendHost = "127.0.0.1";
|
const String kDefaultBackendHost = "127.0.0.1";
|
||||||
const int kDefaultBackendPort = 3551;
|
const int kDefaultBackendPort = 3551;
|
||||||
|
const int kDefaultXmppPort = 80;
|
||||||
@@ -5,7 +5,9 @@ import 'package:path/path.dart' as path;
|
|||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
|
|
||||||
extension FortniteVersionExtension on FortniteVersion {
|
extension FortniteVersionExtension on FortniteVersion {
|
||||||
static File? findExecutable(Directory directory, String name) {
|
static String _marker = "FortniteClient.mod";
|
||||||
|
|
||||||
|
static File? findFile(Directory directory, String name) {
|
||||||
try{
|
try{
|
||||||
final result = directory.listSync(recursive: true)
|
final result = directory.listSync(recursive: true)
|
||||||
.firstWhere((element) => path.basename(element.path) == name);
|
.firstWhere((element) => path.basename(element.path) == name);
|
||||||
@@ -15,28 +17,25 @@ extension FortniteVersionExtension on FortniteVersion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File? get gameExecutable => findExecutable(location, "FortniteClient-Win64-Shipping.exe");
|
Future<File?> get shippingExecutable async {
|
||||||
|
final result = findFile(location, "FortniteClient-Win64-Shipping.exe");
|
||||||
Future<File?> get headlessGameExecutable async {
|
if(result == null) {
|
||||||
final result = findExecutable(location, "FortniteClient-Win64-Shipping-Headless.exe");
|
|
||||||
if(result != null) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
final original = findExecutable(location, "FortniteClient-Win64-Shipping.exe");
|
|
||||||
if(original == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final output = File("${original.parent.path}\\FortniteClient-Win64-Shipping-Headless.exe");
|
final marker = findFile(location, _marker);
|
||||||
await original.copy(output.path);
|
if(marker != null) {
|
||||||
await Isolate.run(() => patchHeadless(output));
|
return result;
|
||||||
return output;
|
}
|
||||||
|
|
||||||
|
await Isolate.run(() => patchHeadless(result));
|
||||||
|
await File("${location.path}\\$_marker").create();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
File? get launcherExecutable => findExecutable(location, "FortniteLauncher.exe");
|
File? get launcherExecutable => findFile(location, "FortniteLauncher.exe");
|
||||||
|
|
||||||
File? get eacExecutable => findExecutable(location, "FortniteClient-Win64-Shipping_EAC.exe");
|
File? get eacExecutable => findFile(location, "FortniteClient-Win64-Shipping_EAC.exe");
|
||||||
|
|
||||||
File? get splashBitmap => findExecutable(location, "Splash.bmp");
|
File? get splashBitmap => findFile(location, "Splash.bmp");
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
|
import 'package:version/version.dart';
|
||||||
|
|
||||||
class FortniteBuild {
|
class FortniteBuild {
|
||||||
final String identifier;
|
final Version version;
|
||||||
final String version;
|
|
||||||
final String link;
|
final String link;
|
||||||
|
final bool available;
|
||||||
|
|
||||||
FortniteBuild({
|
FortniteBuild({
|
||||||
required this.identifier,
|
|
||||||
required this.version,
|
required this.version,
|
||||||
required this.link
|
required this.link,
|
||||||
|
required this.available
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
47
common/lib/src/model/fortnite_server.dart
Normal file
47
common/lib/src/model/fortnite_server.dart
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
class FortniteServer {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final String description;
|
||||||
|
final String author;
|
||||||
|
final String ip;
|
||||||
|
final String version;
|
||||||
|
final String? password;
|
||||||
|
final DateTime timestamp;
|
||||||
|
final bool discoverable;
|
||||||
|
|
||||||
|
FortniteServer({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.description,
|
||||||
|
required this.author,
|
||||||
|
required this.ip,
|
||||||
|
required this.version,
|
||||||
|
required this.password,
|
||||||
|
required this.timestamp,
|
||||||
|
required this.discoverable
|
||||||
|
});
|
||||||
|
|
||||||
|
factory FortniteServer.fromJson(json) => FortniteServer(
|
||||||
|
id: json["id"],
|
||||||
|
name: json["name"],
|
||||||
|
description: json["description"],
|
||||||
|
author: json["author"],
|
||||||
|
ip: json["ip"],
|
||||||
|
version: json["version"],
|
||||||
|
password: json["password"],
|
||||||
|
timestamp: json.containsKey("json") ? DateTime.parse(json["timestamp"]) : DateTime.now(),
|
||||||
|
discoverable: json["discoverable"] ?? false
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"description": description,
|
||||||
|
"author": author,
|
||||||
|
"ip": ip,
|
||||||
|
"version": version,
|
||||||
|
"password": password,
|
||||||
|
"timestamp": timestamp.toString(),
|
||||||
|
"discoverable": discoverable
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:version/version.dart';
|
||||||
|
|
||||||
class FortniteVersion {
|
class FortniteVersion {
|
||||||
String name;
|
Version content;
|
||||||
Directory location;
|
Directory location;
|
||||||
|
|
||||||
FortniteVersion.fromJson(json)
|
FortniteVersion.fromJson(json)
|
||||||
: name = json["name"],
|
: content = Version.parse(json["content"]),
|
||||||
location = Directory(json["location"]);
|
location = Directory(json["location"]);
|
||||||
|
|
||||||
FortniteVersion({required this.name, required this.location});
|
FortniteVersion({required this.content, required this.location});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'name': name,
|
'content': content.toString(),
|
||||||
'location': location.path
|
'location': location.path
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is FortniteVersion && this.content == other.content;
|
||||||
|
}
|
||||||
@@ -9,10 +9,11 @@ class GameInstance {
|
|||||||
final int? launcherPid;
|
final int? launcherPid;
|
||||||
final int? eacPid;
|
final int? eacPid;
|
||||||
final List<InjectableDll> injectedDlls;
|
final List<InjectableDll> injectedDlls;
|
||||||
bool hosting;
|
final GameServerType? serverType;
|
||||||
bool launched;
|
bool launched;
|
||||||
bool movedToVirtualDesktop;
|
bool movedToVirtualDesktop;
|
||||||
bool tokenError;
|
bool tokenError;
|
||||||
|
bool killed;
|
||||||
GameInstance? child;
|
GameInstance? child;
|
||||||
|
|
||||||
GameInstance({
|
GameInstance({
|
||||||
@@ -20,11 +21,21 @@ class GameInstance {
|
|||||||
required this.gamePid,
|
required this.gamePid,
|
||||||
required this.launcherPid,
|
required this.launcherPid,
|
||||||
required this.eacPid,
|
required this.eacPid,
|
||||||
required this.hosting,
|
required this.serverType,
|
||||||
required this.child
|
required this.child
|
||||||
}): tokenError = false, launched = false, movedToVirtualDesktop = false, injectedDlls = [];
|
}): tokenError = false, killed = false, launched = false, movedToVirtualDesktop = false, injectedDlls = [];
|
||||||
|
|
||||||
void kill() {
|
void kill() {
|
||||||
|
GameInstance? child = this;
|
||||||
|
while(child != null) {
|
||||||
|
child._kill();
|
||||||
|
child = child.child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _kill() {
|
||||||
|
launched = true;
|
||||||
|
killed = true;
|
||||||
Process.killPid(gamePid, ProcessSignal.sigabrt);
|
Process.killPid(gamePid, ProcessSignal.sigabrt);
|
||||||
if(launcherPid != null) {
|
if(launcherPid != null) {
|
||||||
Process.killPid(launcherPid!, ProcessSignal.sigabrt);
|
Process.killPid(launcherPid!, ProcessSignal.sigabrt);
|
||||||
@@ -33,17 +44,10 @@ class GameInstance {
|
|||||||
Process.killPid(eacPid!, ProcessSignal.sigabrt);
|
Process.killPid(eacPid!, ProcessSignal.sigabrt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool get nestedHosting {
|
enum GameServerType {
|
||||||
GameInstance? child = this;
|
headless,
|
||||||
while(child != null) {
|
virtualWindow,
|
||||||
if(child.hosting) {
|
window
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
child = child.child;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,11 @@ class ServerResult {
|
|||||||
final StackTrace? stackTrace;
|
final StackTrace? stackTrace;
|
||||||
|
|
||||||
ServerResult(this.type, {this.error, this.stackTrace});
|
ServerResult(this.type, {this.error, this.stackTrace});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ServerResult{type: $type, error: $error, stackTrace: $stackTrace}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ServerResultType {
|
enum ServerResultType {
|
||||||
@@ -21,7 +26,8 @@ enum ServerResultType {
|
|||||||
freePortError,
|
freePortError,
|
||||||
pingingRemote,
|
pingingRemote,
|
||||||
pingingLocal,
|
pingingLocal,
|
||||||
pingError;
|
pingError,
|
||||||
|
processError;
|
||||||
|
|
||||||
bool get isError => name.contains("Error");
|
bool get isError => name.contains("Error");
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ Future<bool> isBackendPortFree() async => await pingBackend(kDefaultBackendHost,
|
|||||||
|
|
||||||
Future<bool> freeBackendPort() async {
|
Future<bool> freeBackendPort() async {
|
||||||
await killProcessByPort(kDefaultBackendPort);
|
await killProcessByPort(kDefaultBackendPort);
|
||||||
|
await killProcessByPort(kDefaultXmppPort);
|
||||||
final standardResult = await isBackendPortFree();
|
final standardResult = await isBackendPortFree();
|
||||||
if(standardResult) {
|
if(standardResult) {
|
||||||
return true;
|
return true;
|
||||||
@@ -35,21 +36,24 @@ Future<bool> freeBackendPort() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Uri?> pingBackend(String host, int port, [bool https=false]) async {
|
Future<Uri?> pingBackend(String host, int port, [bool https=false]) async {
|
||||||
var hostName = host.replaceFirst("http://", "").replaceFirst("https://", "");
|
final hostName = host.replaceFirst("http://", "").replaceFirst("https://", "");
|
||||||
var declaredScheme = host.startsWith("http://") ? "http" : host.startsWith("https://") ? "https" : null;
|
final declaredScheme = host.startsWith("http://") ? "http" : host.startsWith("https://") ? "https" : null;
|
||||||
try{
|
try{
|
||||||
var uri = Uri(
|
final uri = Uri(
|
||||||
scheme: declaredScheme ?? (https ? "https" : "http"),
|
scheme: declaredScheme ?? (https ? "https" : "http"),
|
||||||
host: hostName,
|
host: hostName,
|
||||||
port: port,
|
port: port,
|
||||||
path: "unknown"
|
path: "unknown"
|
||||||
);
|
);
|
||||||
var client = HttpClient()
|
log("[BACKEND] Pinging $uri...");
|
||||||
..connectionTimeout = const Duration(seconds: 5);
|
final client = HttpClient()
|
||||||
var request = await client.getUrl(uri);
|
..connectionTimeout = const Duration(seconds: 10);
|
||||||
var response = await request.close();
|
final request = await client.getUrl(uri);
|
||||||
return response.statusCode == 200 || response.statusCode == 404 ? uri : null;
|
await request.close().timeout(const Duration(seconds: 10));
|
||||||
}catch(_){
|
log("[BACKEND] Ping successful");
|
||||||
|
return uri;
|
||||||
|
}catch(error){
|
||||||
|
log("[BACKEND] Cannot ping backend: $error");
|
||||||
return https || declaredScheme != null || isLocalHost(host) ? null : await pingBackend(host, port, true);
|
return https || declaredScheme != null || isLocalHost(host) ? null : await pingBackend(host, port, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,16 +63,16 @@ Stream<String?> watchMatchmakingIp() async* {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var observer = matchmakerConfigFile.parent.watch(events: FileSystemEvent.modify);
|
final observer = matchmakerConfigFile.parent.watch(events: FileSystemEvent.modify);
|
||||||
yield* observer.where((event) => event.path == matchmakerConfigFile.path).asyncMap((event) async {
|
yield* observer.where((event) => event.path == matchmakerConfigFile.path).asyncMap((event) async {
|
||||||
try {
|
try {
|
||||||
var config = Config.fromString(await matchmakerConfigFile.readAsString());
|
final config = Config.fromString(await matchmakerConfigFile.readAsString());
|
||||||
var ip = config.get("GameServer", "ip");
|
final ip = config.get("GameServer", "ip");
|
||||||
if(ip == null) {
|
if(ip == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var port = config.get("GameServer", "port");
|
final port = config.get("GameServer", "port");
|
||||||
if(port == null) {
|
if(port == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -89,14 +93,14 @@ Stream<String?> watchMatchmakingIp() async* {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> writeMatchmakingIp(String text) async {
|
Future<void> writeMatchmakingIp(String text) async {
|
||||||
var exists = await matchmakerConfigFile.exists();
|
final exists = await matchmakerConfigFile.exists();
|
||||||
if(!exists) {
|
if(!exists) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_semaphore.acquire();
|
_semaphore.acquire();
|
||||||
var splitIndex = text.indexOf(":");
|
final splitIndex = text.indexOf(":");
|
||||||
var ip = splitIndex != -1 ? text.substring(0, splitIndex) : text;
|
final ip = splitIndex != -1 ? text.substring(0, splitIndex) : text;
|
||||||
var port = splitIndex != -1 ? text.substring(splitIndex + 1) : kDefaultGameServerPort;
|
var port = splitIndex != -1 ? text.substring(splitIndex + 1) : kDefaultGameServerPort;
|
||||||
if(port.isBlank) {
|
if(port.isBlank) {
|
||||||
port = kDefaultGameServerPort;
|
port = kDefaultGameServerPort;
|
||||||
@@ -104,7 +108,7 @@ Future<void> writeMatchmakingIp(String text) async {
|
|||||||
|
|
||||||
_lastIp = ip;
|
_lastIp = ip;
|
||||||
_lastPort = port;
|
_lastPort = port;
|
||||||
var config = Config.fromString(await matchmakerConfigFile.readAsString());
|
final config = Config.fromString(await matchmakerConfigFile.readAsString());
|
||||||
config.set("GameServer", "ip", ip);
|
config.set("GameServer", "ip", ip);
|
||||||
config.set("GameServer", "port", port);
|
config.set("GameServer", "port", port);
|
||||||
await matchmakerConfigFile.writeAsString(config.toString(), flush: true);
|
await matchmakerConfigFile.writeAsString(config.toString(), flush: true);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:dio/io.dart';
|
|||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_common/src/extension/types.dart';
|
import 'package:reboot_common/src/extension/types.dart';
|
||||||
|
import 'package:version/version.dart';
|
||||||
|
|
||||||
const String kStopBuildDownloadSignal = "kill";
|
const String kStopBuildDownloadSignal = "kill";
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ Dio _buildDioInstance() {
|
|||||||
return dio;
|
return dio;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String _archiveSourceUrl = "http://185.203.216.3/versions.json";
|
final String _archiveSourceUrl = "https://raw.githubusercontent.com/simplyblk/Fortnitebuilds/main/README.md";
|
||||||
final RegExp _rarProgressRegex = RegExp("^((100)|(\\d{1,2}(.\\d*)?))%\$");
|
final RegExp _rarProgressRegex = RegExp("^((100)|(\\d{1,2}(.\\d*)?))%\$");
|
||||||
const String _deniedConnectionError = "The connection was denied: your firewall might be blocking the download";
|
const String _deniedConnectionError = "The connection was denied: your firewall might be blocking the download";
|
||||||
const String _unavailableError = "The build downloader is not available right now";
|
const String _unavailableError = "The build downloader is not available right now";
|
||||||
@@ -41,15 +42,35 @@ Future<List<FortniteBuild>> fetchBuilds(ignored) async {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
final data = jsonDecode(response.data ?? "{}");
|
|
||||||
var results = <FortniteBuild>[];
|
var results = <FortniteBuild>[];
|
||||||
for(final entry in data.entries) {
|
for (final line in response.data?.split("\n") ?? []) {
|
||||||
results.add(FortniteBuild(
|
if (!line.startsWith("|")) {
|
||||||
identifier: entry.key,
|
continue;
|
||||||
version: "${entry.value["title"]} (${entry.key})",
|
}
|
||||||
link: entry.value["url"]
|
|
||||||
));
|
var parts = line.substring(1, line.length - 1).split("|");
|
||||||
|
if (parts.isEmpty) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var versionName = parts.first.trim();
|
||||||
|
final separator = versionName.indexOf("-");
|
||||||
|
if(separator != -1) {
|
||||||
|
versionName = versionName.substring(0, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
final link = parts.last.trim();
|
||||||
|
try {
|
||||||
|
results.add(FortniteBuild(
|
||||||
|
version: Version.parse(versionName),
|
||||||
|
link: link,
|
||||||
|
available: link.endsWith(".zip") || link.endsWith(".rar")
|
||||||
|
));
|
||||||
|
} on FormatException {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +88,7 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final startTime = DateTime.now().millisecondsSinceEpoch;
|
final startTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
final response = _downloadArchive(options, tempFile, startTime);
|
final response = _downloadArchive(options, stopped, tempFile, startTime);
|
||||||
await Future.any([stopped.future, response]);
|
await Future.any([stopped.future, response]);
|
||||||
if(!stopped.isCompleted) {
|
if(!stopped.isCompleted) {
|
||||||
await _extractArchive(stopped, extension, tempFile, options);
|
await _extractArchive(stopped, extension, tempFile, options);
|
||||||
@@ -79,13 +100,17 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _downloadArchive(FortniteBuildDownloadOptions options, File tempFile, int startTime, [int? byteStart = null, int errorsCount = 0]) async {
|
Future<void> _downloadArchive(FortniteBuildDownloadOptions options, Completer stopped, File tempFile, int startTime, [int? byteStart = null, int errorsCount = 0]) async {
|
||||||
var received = byteStart ?? 0;
|
var received = byteStart ?? 0;
|
||||||
try {
|
try {
|
||||||
await _dio.download(
|
await _dio.download(
|
||||||
options.build.link,
|
options.build.link,
|
||||||
tempFile.path,
|
tempFile.path,
|
||||||
onReceiveProgress: (data, length) {
|
onReceiveProgress: (data, length) {
|
||||||
|
if(stopped.isCompleted) {
|
||||||
|
throw StateError("Download interrupted");
|
||||||
|
}
|
||||||
|
|
||||||
received = data;
|
received = data;
|
||||||
final percentage = (received / length) * 100;
|
final percentage = (received / length) * 100;
|
||||||
_onProgress(startTime, percentage < 1 ? null : DateTime.now().millisecondsSinceEpoch, percentage, false, options);
|
_onProgress(startTime, percentage < 1 ? null : DateTime.now().millisecondsSinceEpoch, percentage, false, options);
|
||||||
@@ -116,12 +141,16 @@ Future<void> _downloadArchive(FortniteBuildDownloadOptions options, File tempFil
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
|
if(stopped.isCompleted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(errorsCount > _maxErrors || error.toString().contains(_deniedConnectionError) || error.toString().contains(_unavailableError)) {
|
if(errorsCount > _maxErrors || error.toString().contains(_deniedConnectionError) || error.toString().contains(_unavailableError)) {
|
||||||
_onError(error, options);
|
_onError(error, options);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _downloadArchive(options, tempFile, startTime, received, errorsCount + 1);
|
await _downloadArchive(options, stopped, tempFile, startTime, received, errorsCount + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +254,7 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
}
|
}
|
||||||
|
|
||||||
await Future.any([stopped.future, process.exitCode]);
|
await Future.any([stopped.future, process.exitCode]);
|
||||||
|
process.kill(ProcessSignal.sigabrt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onProgress(int startTime, int? now, double percentage, bool extracting, FortniteBuildDownloadOptions options) {
|
void _onProgress(int startTime, int? now, double percentage, bool extracting, FortniteBuildDownloadOptions options) {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ Future<bool> hasRebootDllUpdate(int? lastUpdateMs, {int hours = 24, bool force =
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> downloadCriticalDll(String name, String outputPath) async {
|
Future<void> downloadCriticalDll(String name, String outputPath) async {
|
||||||
print("https://github.com/Auties00/reboot_launcher/raw/master/gui/dependencies/dlls/$name");
|
|
||||||
final response = await http.get(Uri.parse("https://github.com/Auties00/reboot_launcher/raw/master/gui/dependencies/dlls/$name"));
|
final response = await http.get(Uri.parse("https://github.com/Auties00/reboot_launcher/raw/master/gui/dependencies/dlls/$name"));
|
||||||
if(response.statusCode != 200) {
|
if(response.statusCode != 200) {
|
||||||
throw Exception("Cannot download $name: status code ${response.statusCode}");
|
throw Exception("Cannot download $name: status code ${response.statusCode}");
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'dart:io';
|
|||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:sync/semaphore.dart';
|
import 'package:sync/semaphore.dart';
|
||||||
|
|
||||||
final File _loggingFile = _createLoggingFile();
|
final File launcherLogFile = _createLoggingFile();
|
||||||
final Semaphore _semaphore = Semaphore(1);
|
final Semaphore _semaphore = Semaphore(1);
|
||||||
|
|
||||||
File _createLoggingFile() {
|
File _createLoggingFile() {
|
||||||
@@ -20,9 +20,9 @@ void log(String message) async {
|
|||||||
try {
|
try {
|
||||||
await _semaphore.acquire();
|
await _semaphore.acquire();
|
||||||
print(message);
|
print(message);
|
||||||
await _loggingFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
|
await launcherLogFile.writeAsString("$message\n", mode: FileMode.append, flush: true);
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
print(error);
|
print("[LOGGER_ERROR] An error occurred while logging: $error");
|
||||||
}finally {
|
}finally {
|
||||||
_semaphore.release();
|
_semaphore.release();
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ final Uint8List _patchedHeadless = Uint8List.fromList([
|
|||||||
45, 0, 108, 0, 111, 0, 103, 0, 32, 0, 45, 0, 110, 0, 111, 0, 115, 0, 112, 0, 108, 0, 97, 0, 115, 0, 104, 0, 32, 0, 45, 0, 110, 0, 111, 0, 115, 0, 111, 0, 117, 0, 110, 0, 100, 0, 32, 0, 45, 0, 110, 0, 117, 0, 108, 0, 108, 0, 114, 0, 104, 0, 105, 0, 32, 0, 45, 0, 117, 0, 115, 0, 101, 0, 111, 0, 108, 0, 100, 0, 105, 0, 116, 0, 101, 0, 109, 0, 99, 0, 97, 0, 114, 0, 100, 0, 115, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0
|
45, 0, 108, 0, 111, 0, 103, 0, 32, 0, 45, 0, 110, 0, 111, 0, 115, 0, 112, 0, 108, 0, 97, 0, 115, 0, 104, 0, 32, 0, 45, 0, 110, 0, 111, 0, 115, 0, 111, 0, 117, 0, 110, 0, 100, 0, 32, 0, 45, 0, 110, 0, 117, 0, 108, 0, 108, 0, 114, 0, 104, 0, 105, 0, 32, 0, 45, 0, 117, 0, 115, 0, 101, 0, 111, 0, 108, 0, 100, 0, 105, 0, 116, 0, 101, 0, 109, 0, 99, 0, 97, 0, 114, 0, 100, 0, 115, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Not used right now
|
||||||
final Uint8List _originalMatchmaking = Uint8List.fromList([
|
final Uint8List _originalMatchmaking = Uint8List.fromList([
|
||||||
63, 0, 69, 0, 110, 0, 99, 0, 114, 0, 121, 0, 112, 0, 116, 0, 105, 0, 111, 0, 110, 0, 84, 0, 111, 0, 107, 0, 101, 0, 110, 0, 61
|
63, 0, 69, 0, 110, 0, 99, 0, 114, 0, 121, 0, 112, 0, 116, 0, 105, 0, 111, 0, 110, 0, 84, 0, 111, 0, 107, 0, 101, 0, 110, 0, 61
|
||||||
]);
|
]);
|
||||||
@@ -18,7 +19,7 @@ final Uint8List _patchedMatchmaking = Uint8List.fromList([
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
Future<bool> patchHeadless(File file) async =>
|
Future<bool> patchHeadless(File file) async =>
|
||||||
_patch(file, _originalHeadless, _patchedHeadless);
|
await _patch(file, _originalHeadless, _patchedHeadless);
|
||||||
|
|
||||||
Future<bool> patchMatchmaking(File file) async =>
|
Future<bool> patchMatchmaking(File file) async =>
|
||||||
await _patch(file, _originalMatchmaking, _patchedMatchmaking);
|
await _patch(file, _originalMatchmaking, _patchedMatchmaking);
|
||||||
@@ -29,22 +30,24 @@ Future<bool> _patch(File file, Uint8List original, Uint8List patched) async {
|
|||||||
throw Exception("Cannot mutate length of binary file");
|
throw Exception("Cannot mutate length of binary file");
|
||||||
}
|
}
|
||||||
|
|
||||||
final read = await file.readAsBytes();
|
final source = await file.readAsBytes();
|
||||||
final length = await file.length();
|
|
||||||
var readOffset = 0;
|
var readOffset = 0;
|
||||||
var patchOffset = -1;
|
var patchOffset = -1;
|
||||||
var patchCount = 0;
|
var patchCount = 0;
|
||||||
while(readOffset < length){
|
while(readOffset < source.length){
|
||||||
if(read[readOffset] == original[patchCount]){
|
if(source[readOffset] == original[patchCount]){
|
||||||
if(patchOffset == -1) {
|
if(patchOffset == -1) {
|
||||||
patchOffset = readOffset;
|
patchOffset = readOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(++patchCount == original.length) {
|
if(readOffset - patchOffset + 1 == original.length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patchCount++;
|
||||||
}else {
|
}else {
|
||||||
patchOffset = -1;
|
patchOffset = -1;
|
||||||
|
patchCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
readOffset++;
|
readOffset++;
|
||||||
@@ -55,10 +58,10 @@ Future<bool> _patch(File file, Uint8List original, Uint8List patched) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(var i = 0; i < patched.length; i++) {
|
for(var i = 0; i < patched.length; i++) {
|
||||||
read[patchOffset + i] = patched[i];
|
source[patchOffset + i] = patched[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
await file.writeAsBytes(read, flush: true);
|
await file.writeAsBytes(source, flush: true);
|
||||||
return true;
|
return true;
|
||||||
}catch(_){
|
}catch(_){
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Directory get installationDirectory =>
|
|||||||
Directory get dllsDirectory => Directory("${installationDirectory.path}\\dlls");
|
Directory get dllsDirectory => Directory("${installationDirectory.path}\\dlls");
|
||||||
|
|
||||||
Directory get assetsDirectory {
|
Directory get assetsDirectory {
|
||||||
var directory = Directory("${installationDirectory.path}\\data\\flutter_assets\\assets");
|
final directory = Directory("${installationDirectory.path}\\data\\flutter_assets\\assets");
|
||||||
if(directory.existsSync()) {
|
if(directory.existsSync()) {
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user