52 Commits

Author SHA1 Message Date
Alessandro Autiero
4327541ac6 Merge pull request #257 from Milxnor/master
Added dedicated_server endpoints & Update keychain
2025-03-23 16:33:39 +01:00
Gray
64dc971da4 Added dedicated_server endpoints 2025-03-22 07:47:46 -04:00
Gray
d36da909ed Update keychain (for events and new cosmetics) 2025-03-22 07:47:25 -04:00
Alessandro Autiero
90448eeaa1 10.0.7 2025-03-08 17:06:01 +01:00
Alessandro Autiero
b319479def 10.0.6 2025-02-04 13:50:01 +01:00
Alessandro Autiero
d5e41ed646 10.0.5 2024-12-30 19:13:08 +01:00
Alessandro Autiero
9e20ec86e6 Merge remote-tracking branch 'origin/master' 2024-12-29 21:43:04 +01:00
Alessandro Autiero
004fc41292 Dependency 2024-12-29 21:42:54 +01:00
Alessandro Autiero
ee466df630 Update README.md 2024-12-24 21:52:06 +01:00
Alessandro Autiero
fdb1d694d9 Better moving system 2024-12-10 17:18:10 +01:00
Alessandro Autiero
0cfa4af236 10.0.4 2024-12-10 14:45:56 +01:00
Alessandro Autiero
d42946c44b 10.0.3 2024-12-09 22:28:24 +01:00
Alessandro Autiero
0a59a32c1b 10.0.2 2024-12-09 14:36:43 +01:00
Alessandro Autiero
2046cb14f6 10.0 2024-12-09 12:59:14 +01:00
Alessandro Autiero
e3f7a1d2cc 10.0 2024-12-09 12:49:21 +01:00
Alessandro Autiero
cd6752ed3f Merge pull request #169 from Auties00/_onLoggedIn
10.0
2024-12-09 12:44:14 +01:00
Alessandro Autiero
e1df46efd9 10.0 2024-12-09 12:42:49 +01:00
Alessandro Autiero
dccd05e57f Merge pull request #168 from Auties00/_onLoggedIn
10.0
2024-12-09 12:15:20 +01:00
Alessandro Autiero
eb7745cc4d 10.0 2024-12-09 12:14:41 +01:00
Alessandro Autiero
7d5e17642a Merge pull request #166 from Auties00/_onLoggedIn
Switched to starfall.dll
2024-12-08 20:42:54 +01:00
Alessandro Autiero
6f91ad0404 Switched to starfall.dll 2024-12-08 20:41:31 +01:00
Alessandro Autiero
0c38528e77 Merge pull request #118 from Auties00/_onLoggedIn
On logged in
2024-10-21 22:34:47 +02:00
Alessandro Autiero
dfebe74518 Switched to sinum 2024-10-21 20:32:23 +02:00
Alessandro Autiero
bfe15e43d9 Released 9.2.7 2024-09-14 12:37:56 +02:00
Alessandro Autiero
62dae468bf Merge pull request #98 from Auties00/_onLoggedIn
Released 9.2.6
2024-09-12 17:49:12 +02:00
Alessandro Autiero
a9af28273a Released 9.2.6 2024-09-12 15:46:24 +02:00
Alessandro Autiero
232bf8fbfc Update README.md 2024-08-18 22:35:17 +02:00
Alessandro Autiero
a787c4efc9 Merge pull request #86 from Auties00/_onLoggedIn
Release 9.2.5
2024-08-18 22:34:36 +02:00
Alessandro Autiero
4c3fe9bc65 Released 9.2.5 2024-08-18 20:29:09 +02:00
Alessandro Autiero
3f88d5ed80 Create .gitattributes 2024-07-31 11:54:02 +02:00
Alessandro Autiero
582270849e Released 9.2.4 2024-07-10 15:40:52 +02:00
Alessandro Autiero
1ef4e76768 Small fix to display errors and warnings from backend 2024-07-10 15:19:20 +02:00
Alessandro Autiero
cd8c8e6dd9 Release 9.2.3 2024-07-10 15:11:49 +02:00
Alessandro Autiero
170a878e79 Merge pull request #69 from Auties00/_onLoggedIn
Release 9.2.2
2024-07-09 22:38:47 +02:00
Alessandro Autiero
a2505011d9 Release 9.2.2 2024-07-09 20:38:01 +02:00
Alessandro Autiero
3e2c2e96b1 Release 9.2.1 2024-07-07 10:17:07 +02:00
Alessandro Autiero
00802ac6da Merge pull request #65 from Auties00/_onLoggedIn
Release 9.2.0
2024-07-06 20:44:33 +02:00
Alessandro Autiero
1d68469297 Merge pull request #64 from Auties00/_onLoggedIn
Port Forwarding documentation
2024-07-06 20:35:08 +02:00
Alessandro Autiero
83878db8c5 Merge pull request #63 from Auties00/_onLoggedIn
Portforwarding documentation
2024-07-06 20:33:57 +02:00
Alessandro Autiero
e3b8d7d182 Release 9.2.0 2024-07-06 18:43:52 +02:00
Alessandro Autiero
45b8629207 Port Forwarding documentation 2024-07-06 18:34:42 +02:00
Alessandro Autiero
2df1b81485 Port Forwarding documentation 2024-07-06 18:33:22 +02:00
Alessandro Autiero
018ccb7f8e Merge pull request #57 from Auties00/_onLoggedIn
9.1.4
2024-06-15 19:57:54 +02:00
Alessandro Autiero
0d64251623 Reversed logging 2024-06-15 18:48:42 +02:00
Alessandro Autiero
47adb572ea Added back logging 2024-06-15 18:40:46 +02:00
Alessandro Autiero
e3a42d6b81 Fixed small bug 2024-06-15 18:23:43 +02:00
Alessandro Autiero
e24f4e97b3 9.1.4 2024-06-15 17:57:17 +02:00
Alessandro Autiero
0a775e2f3f Merge pull request #52 from Auties00/_onLoggedIn
9.1.3
2024-06-04 22:32:10 +02:00
Alessandro Autiero
2bf084d120 9.1.3 2024-06-04 20:31:06 +02:00
Alessandro Autiero
93c5d6c56b Stuff 2024-06-03 16:27:52 +02:00
Alessandro Autiero
46034aa1fa Stuff 2024-06-03 16:26:04 +02:00
Alessandro Autiero
3069f3aa05 9.1.0 2024-06-02 16:54:48 +02:00
228 changed files with 8803 additions and 7123 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
backend/**/* linguist-vendored

View File

@@ -1,9 +1,16 @@
# Reboot Launcher ![Banner](https://i.imgur.com/p0P4tcI.png)
![Screenshot (34)](https://github.com/Auties00/reboot_launcher/assets/28218457/de2cac8e-7060-4e11-a91f-e01e3c174b9c) GUI and CLI Launcher for [Project Reboot](https://github.com/Milxnor/Project-Reboot-3.0/)
![Screenshot (35)](https://github.com/Auties00/reboot_launcher/assets/28218457/de43d2b8-09fc-4d34-beb1-aa6f7fcaa479) Join our [Discord](https://discord.gg/rebootmp)
![Screenshot (36)](https://github.com/Auties00/reboot_launcher/assets/28218457/3337f5cd-81d6-45d8-ab47-8018fb8a6cee)
![Screenshot (37)](https://github.com/Auties00/reboot_launcher/assets/28218457/51086ec7-5e68-4411-b704-7837970741c8) ## Modules
![Screenshot (38)](https://github.com/Auties00/reboot_launcher/assets/28218457/9aca3e00-85e3-4580-95bd-fef8b389f40b)
![Screenshot (39)](https://github.com/Auties00/reboot_launcher/assets/28218457/faa5d3a3-18c2-4d53-84c5-6eadc0bf4069) - COMMON: Shared business logic for CLI and GUI modules
![Screenshot (33)](https://github.com/Auties00/reboot_launcher/assets/28218457/6c449aa6-e515-4680-9ee2-d219761f3268) - CLI: Work in progress command line interface to host a Fortnite Server on a Windows VPS easily, developed in Dart
- GUI: Stable graphical user interface to play and host Fortnite S0-14
![image](https://github.com/user-attachments/assets/7ff5d49e-8920-41ad-a805-188d84ad6ec4)
## Installation
Check the releases section

View File

4
backend/README.md vendored Normal file
View File

@@ -0,0 +1,4 @@
# Backend
Fork of LawinV1
Awaiting rewrite in Dart
Use build.bat to generate the executable

View File

@@ -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'));
@@ -25,7 +35,7 @@ express.use(require("./structure/matchmaking.js"));
express.use(require("./structure/cloudstorage.js")); express.use(require("./structure/cloudstorage.js"));
express.use(require("./structure/mcp.js")); express.use(require("./structure/mcp.js"));
const port = process.env.PORT || 3551; const port = 3551;
express.listen(port, () => { express.listen(port, () => {
console.log("LawinServer started listening on port", port); console.log("LawinServer started listening on port", port);

0
backend/install_packages.bat vendored Normal file
View File

View File

@@ -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",

View File

@@ -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 vendored Normal file
View File

0
backend/public/images/discord.png vendored Normal file
View File

0
backend/public/images/lawin-s.png vendored Normal file
View File

0
backend/public/images/lawin.jpg vendored Normal file
View File

0
backend/public/images/motd-s.png vendored Normal file
View File

0
backend/public/images/motd.png vendored Normal file
View File

0
backend/public/images/seasonx.png vendored Normal file
View File

View File

View File

View 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
} }
] ]

View File

@@ -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": [],

File diff suppressed because it is too large Load Diff

View File

@@ -7932,6 +7932,35 @@ express.post("/fortnite/api/game/v2/profile/*/client/SetHeroCosmeticVariants", a
res.end(); res.end();
}); });
// any dedicated_server request
express.post("/fortnite/api/game/v2/profile/*/dedicated_server/*", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`);
// do not change any of these or you will end up breaking it
var ApplyProfileChanges = [];
var BaseRevision = profile.rvn || 0;
var QueryRevision = req.query.rvn || -1;
// this doesn't work properly on version v12.20 and above but whatever
if (QueryRevision != BaseRevision) {
ApplyProfileChanges = [{
"changeType": "fullProfileUpdate",
"profile": profile
}];
}
res.json({
"profileRevision": profile.rvn || 0,
"profileId": req.query.profileId || "athena",
"profileChangesBaseRevision": BaseRevision,
"profileChanges": ApplyProfileChanges,
"profileCommandRevision": profile.commandRevision || 0,
"serverTime": new Date().toISOString(),
"responseVersion": 1
})
res.end();
});
// any mcp request that doesn't have something assigned to it // any mcp request that doesn't have something assigned to it
express.post("/fortnite/api/game/v2/profile/*/client/*", async (req, res) => { express.post("/fortnite/api/game/v2/profile/*/client/*", async (req, res) => {
const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`); const profile = require(`./../profiles/${req.query.profileId || "athena"}.json`);

View File

@@ -1,88 +1,89 @@
import 'dart:io'; import 'dart:collection';
import 'package:args/args.dart'; class Parser {
import 'package:reboot_cli/src/game.dart'; final List<Command> commands;
import 'package:reboot_cli/src/reboot.dart';
import 'package:reboot_cli/src/server.dart';
import 'package:reboot_common/common.dart';
import 'package:reboot_common/src/util/matchmaker.dart' as matchmaker;
late String? username; Parser({required this.commands});
late bool host;
late bool verbose;
late String dll;
late FortniteVersion version;
late bool autoRestart;
void main(List<String> args) async { CommandCall? parse(List<String> args) {
stdout.writeln("Reboot Launcher"); var position = 0;
stdout.writeln("Wrote by Auties00"); var allowedCommands = _toMap(commands);
stdout.writeln("Version 1.0"); var allowedParameters = <String>{};
Command? command;
kill(); CommandCall? head;
CommandCall? tail;
var parser = ArgParser() String? parameterName;
..addOption("path", mandatory: true) while(position < args.length) {
..addOption("username") final current = args[position].toLowerCase();
..addOption("server-type", allowed: ServerType.values.map((entry) => entry.name), defaultsTo: ServerType.embedded.name) if(parameterName != null) {
..addOption("server-host") tail?.parameters[parameterName] = current;
..addOption("server-port") parameterName = null;
..addOption("matchmaking-address") }else if(allowedParameters.contains(current.toLowerCase())) {
..addOption("dll", defaultsTo: rebootDllFile.path) parameterName = current.substring(2);
..addFlag("update", defaultsTo: true, negatable: true) if(args.elementAtOrNull(position + 1) == '"') {
..addFlag("log", defaultsTo: false) position++;
..addFlag("host", defaultsTo: false) }
..addFlag("auto-restart", defaultsTo: false, negatable: true); }else {
var result = parser.parse(args); final newCommand = allowedCommands[current];
if(newCommand != null) {
dll = result["dll"]; final newCall = CommandCall(name: newCommand.name);
host = result["host"]; if(head == null) {
username = result["username"] ?? kDefaultPlayerName; head = newCall;
verbose = result["log"]; tail = newCall;
version = FortniteVersion(name: "Dummy", location: Directory(result["path"])); }
if(tail != null) {
await downloadRequiredDLLs(); tail.subCall = newCall;
if(result["update"]) { }
stdout.writeln("Updating reboot dll..."); tail = newCall;
try { command = newCommand;
await downloadRebootDll(kRebootDownloadUrl); allowedCommands = _toMap(newCommand.subCommands);
}catch(error){ allowedParameters = _toParameters(command);
stderr.writeln("Cannot update reboot dll: $error"); }
}
position++;
} }
return head;
} }
stdout.writeln("Launching game..."); Set<String> _toParameters(Command? parent) => parent?.parameters
var executable = version.gameExecutable; .map((e) => '--${e.toLowerCase()}')
if(executable == null){ .toSet() ?? {};
throw Exception("Missing game executable at: ${version.location.path}");
}
final serverHost = result["server-host"]?.trim(); Map<String, Command> _toMap(List<Command> children) => Map.fromIterable(
if(serverHost?.isEmpty == true){ children,
throw Exception("Missing host name"); key: (command) => command.name.toLowerCase(),
} value: (command) => command
final serverPort = result["server-port"]?.trim();
if(serverPort?.isEmpty == true){
throw Exception("Missing port");
}
final serverPortNumber = serverPort == null ? null : int.tryParse(serverPort);
if(serverPort != null && serverPortNumber == null){
throw Exception("Invalid port, use only numbers");
}
var started = await startServerCli(
serverHost,
serverPortNumber,
ServerType.values.firstWhere((element) => element.name == result["server-type"])
); );
if(!started){ }
stderr.writeln("Cannot start server!");
return;
}
matchmaker.writeMatchmakingIp(result["matchmaking-address"]); class Command {
autoRestart = result["auto-restart"]; final String name;
await startGame(); final List<String> parameters;
final List<Command> subCommands;
const Command({required this.name, required this.parameters, required this.subCommands});
@override
String toString() => 'Command{name: $name, parameters: $parameters, subCommands: $subCommands}';
}
class Parameter {
final String name;
final bool Function(String) validator;
const Parameter({required this.name, required this.validator});
@override
String toString() => 'Parameter{name: $name, validator: $validator}';
}
class CommandCall {
final String name;
final Map<String, String> parameters;
CommandCall? subCall;
CommandCall({required this.name}) : parameters = {};
@override
String toString() => 'CommandCall{name: $name, parameters: $parameters, subCall: $subCall}';
} }

102
cli/lib/main.dart Normal file
View File

@@ -0,0 +1,102 @@
import 'package:interact/interact.dart';
import 'package:reboot_cli/cli.dart';
import 'package:tint/tint.dart';
const Command _buildImport = Command(name: 'import', parameters: ['version', 'path'], subCommands: []);
const Command _buildDownload = Command(name: 'download', parameters: ['version', 'path'], subCommands: []);
const Command _build = Command(name: 'build', parameters: [], subCommands: [_buildImport, _buildDownload]);
const Command _play = Command(name: 'play', parameters: [], subCommands: []);
const Command _host = Command(name: 'host', parameters: [], subCommands: []);
const Command _backend = Command(name: 'backend', parameters: [], subCommands: []);
void main(List<String> args) {
_welcome();
final parser = Parser(commands: [_build, _play, _host, _backend]);
final command = parser.parse(args);
print(command);
_handleRootCommand(command);
}
void _handleRootCommand(CommandCall? call) {
switch(call == null ? null : call.name) {
case 'build':
_handleBuildCommand(call?.subCall);
break;
case 'play':
_handleBuildCommand(call?.subCall);
break;
case 'host':
_handleBuildCommand(call?.subCall);
break;
case 'backend':
_handleBuildCommand(call?.subCall);
break;
default:
_askRootCommand();
break;
}
}
void _askRootCommand() {
final commands = [_build.name, _play.name, _host.name, _backend.name];
final commandSelector = Select.withTheme(
prompt: ' Select a command:',
options: commands,
theme: Theme.colorfulTheme.copyWith(inputPrefix: '', inputSuffix: '')
);
_handleRootCommand(CommandCall(name: commands[commandSelector.interact()]));
}
void _handleBuildCommand(CommandCall? call) {
switch(call == null ? null : call.name) {
case 'import':
_handleBuildImportCommand(call!);
break;
case 'download':
_handleBuildDownloadCommand(call!);
break;
default:
_askBuildCommand();
break;
}
}
void _handleBuildImportCommand(CommandCall call) {
final version = call.parameters['path'];
final path = call.parameters['path'];
print(version);
print(path);
}
void _handleBuildDownloadCommand(CommandCall call) {
}
void _askBuildCommand() {
final commands = [_buildImport.name, _buildDownload.name];
final commandSelector = Select.withTheme(
prompt: ' Select a build command:',
options: commands,
theme: Theme.colorfulTheme.copyWith(inputPrefix: '', inputSuffix: '')
);
_handleBuildCommand(CommandCall(name: commands[commandSelector.interact()]));
}
void _handlePlayCommand(CommandCall? call) {
}
void _handleHostCommand(CommandCall? call) {
}
void _handleBackendCommand(CommandCall? call) {
}
void _welcome() => print("""
🎮 Reboot Launcher
🔥 Launch, manage, and play Fortnite using Project Reboot!
🚀 Developed by Auties00 - Version 10.0.7
""".green());

View File

@@ -1,112 +0,0 @@
import 'dart:io';
import 'package:process_run/process_run.dart';
import 'package:reboot_cli/cli.dart';
import 'package:reboot_common/common.dart';
Process? _gameProcess;
Process? _launcherProcess;
Process? _eacProcess;
Future<void> startGame() async {
await _startLauncherProcess(version);
await _startEacProcess(version);
var executable = await version.gameExecutable;
if (executable == null) {
throw Exception("${version.location.path} no longer contains a Fortnite executable, did you delete or move it?");
}
if (username == null) {
username = "Reboot${host ? 'Host' : 'Player'}";
stdout.writeln("No username was specified, using $username by default. Use --username to specify one");
}
_gameProcess = await Process.start(executable.path, createRebootArgs(username!, "", host, host, ""))
..exitCode.then((_) => _onClose())
..outLines.forEach((line) => _onGameOutput(line, dll, host, verbose));
_injectOrShowError("cobalt.dll");
}
Future<void> _startLauncherProcess(FortniteVersion dummyVersion) async {
if (dummyVersion.launcherExecutable == null) {
return;
}
_launcherProcess = await Process.start(dummyVersion.launcherExecutable!.path, []);
suspend(_launcherProcess!.pid);
}
Future<void> _startEacProcess(FortniteVersion dummyVersion) async {
if (dummyVersion.eacExecutable == null) {
return;
}
_eacProcess = await Process.start(dummyVersion.eacExecutable!.path, []);
suspend(_eacProcess!.pid);
}
void _onGameOutput(String line, String dll, bool hosting, bool verbose) {
if(verbose) {
stdout.writeln(line);
}
if (line.contains(kShutdownLine)) {
_onClose();
return;
}
if(kCannotConnectErrors.any((element) => line.contains(element))){
stderr.writeln("The backend doesn't work! Token expired");
_onClose();
return;
}
if(line.contains("Region ")){
if(hosting) {
_injectOrShowError(dll, false);
}else {
_injectOrShowError("console.dll");
}
_injectOrShowError("memoryleak.dll");
}
}
void _kill() {
_gameProcess?.kill(ProcessSignal.sigabrt);
_launcherProcess?.kill(ProcessSignal.sigabrt);
_eacProcess?.kill(ProcessSignal.sigabrt);
}
Future<void> _injectOrShowError(String binary, [bool locate = true]) async {
if (_gameProcess == null) {
return;
}
try {
stdout.writeln("Injecting $binary...");
var dll = locate ? File("${assetsDirectory.path}\\dlls\\$binary") : File(binary);
if(!dll.existsSync()){
throw Exception("Cannot inject $dll: missing file");
}
await injectDll(_gameProcess!.pid, dll.path);
} catch (exception) {
throw Exception("Cannot inject binary: $binary");
}
}
void _onClose() {
_kill();
sleep(const Duration(seconds: 3));
stdout.writeln("The game was closed");
if(autoRestart){
stdout.writeln("Restarting automatically game");
startGame();
return;
}
exit(0);
}

View File

@@ -1,55 +0,0 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:http/http.dart' as http;
import 'package:reboot_common/common.dart';
// TODO: Use github
const String _baseDownload = "https://cdn.discordapp.com/attachments/1095351875961901057/1110968021373169674/cobalt.dll";
const String _consoleDownload = "https://cdn.discordapp.com/attachments/1095351875961901057/1110968095033524234/console.dll";
const String _memoryFixDownload = "https://cdn.discordapp.com/attachments/1095351875961901057/1110968141556756581/memoryleak.dll";
const String _embeddedConfigDownload = "https://cdn.discordapp.com/attachments/1026121175878881290/1040679319351066644/embedded.zip";
Future<void> downloadRequiredDLLs() async {
stdout.writeln("Downloading necessary components...");
var consoleDll = File("${assetsDirectory.path}\\dlls\\console.dll");
if(!consoleDll.existsSync()){
var response = await http.get(Uri.parse(_consoleDownload));
if(response.statusCode != 200){
throw Exception("Cannot download console.dll");
}
await consoleDll.writeAsBytes(response.bodyBytes);
}
var craniumDll = File("${assetsDirectory.path}\\dlls\\cobalt.dll");
if(!craniumDll.existsSync()){
var response = await http.get(Uri.parse(_baseDownload));
if(response.statusCode != 200){
throw Exception("Cannot download cobalt.dll");
}
await craniumDll.writeAsBytes(response.bodyBytes);
}
var memoryFixDll = File("${assetsDirectory.path}\\dlls\\memoryleak.dll");
if(!memoryFixDll.existsSync()){
var response = await http.get(Uri.parse(_memoryFixDownload));
if(response.statusCode != 200){
throw Exception("Cannot download memoryleak.dll");
}
await memoryFixDll.writeAsBytes(response.bodyBytes);
}
if(!backendDirectory.existsSync()){
var response = await http.get(Uri.parse(_embeddedConfigDownload));
if(response.statusCode != 200){
throw Exception("Cannot download embedded server config");
}
var tempZip = File("${tempDirectory.path}/reboot_config.zip");
await tempZip.writeAsBytes(response.bodyBytes);
await extractFileToDisk(tempZip.path, backendDirectory.path);
}
}

View File

@@ -1,60 +0,0 @@
import 'dart:io';
import 'package:reboot_common/common.dart';
import 'package:reboot_common/src/util/backend.dart' as server;
Future<bool> startServerCli(String? host, int? port, ServerType type) async {
stdout.writeln("Starting backend server...");
switch(type){
case ServerType.local:
var result = await pingBackend(host ?? kDefaultBackendHost, port ?? kDefaultBackendPort);
if(result == null){
throw Exception("Local backend server is not running");
}
stdout.writeln("Detected local backend server");
return true;
case ServerType.embedded:
stdout.writeln("Starting an embedded server...");
await server.startEmbeddedBackend(false);
var result = await pingBackend(host ?? kDefaultBackendHost, port ?? kDefaultBackendPort);
if(result == null){
throw Exception("Cannot start embedded server");
}
return true;
case ServerType.remote:
if(host == null){
throw Exception("Missing host for remote server");
}
if(port == null){
throw Exception("Missing host for remote server");
}
stdout.writeln("Starting a reverse proxy to $host:$port");
return await _changeReverseProxyState(host, port) != null;
}
}
Future<HttpServer?> _changeReverseProxyState(String host, int port) async {
try{
var uri = await pingBackend(host, port);
if(uri == null){
return null;
}
return await server.startRemoteBackendProxy(uri);
}catch(error){
throw Exception("Cannot start reverse proxy");
}
}
void kill() async {
try {
await Process.run("taskkill", ["/f", "/im", "FortniteLauncher.exe"]);
await Process.run("taskkill", ["/f", "/im", "FortniteClient-Win64-Shipping_EAC.exe"]);
}catch(_){
}
}

View File

@@ -1,17 +1,18 @@
name: reboot_cli name: reboot_cli
description: Command Line Interface for Project Reboot description: Command Line Interface for Project Reboot
version: "1.0.0" version: "10.0.7"
publish_to: 'none' publish_to: 'none'
environment: environment:
sdk: ">=2.19.0 <=3.3.4" sdk: ">=2.19.0 <=3.5.3"
dependencies: dependencies:
reboot_common: reboot_common:
path: ./../common path: ./../common
args: ^2.3.1 tint: ^2.0.1
process_run: ^0.13.1 interact: ^2.2.0
args: ^2.6.0
dependency_overrides: dependency_overrides:
xml: ^6.3.0 xml: ^6.3.0

View File

@@ -10,10 +10,13 @@ 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/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';
export 'package:reboot_common/src/util/dll.dart'; 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';

View File

@@ -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;

View File

@@ -1,4 +1,5 @@
const String kDefaultPlayerName = "Player"; const String kDefaultPlayerName = "Player";
const String kDefaultHostName = "Host";
const String kDefaultGameServerHost = "127.0.0.1"; const String kDefaultGameServerHost = "127.0.0.1";
const String kDefaultGameServerPort = "7777"; const String kDefaultGameServerPort = "7777";
const String kInitializedLine = "Game Engine Initialized"; const String kInitializedLine = "Game Engine Initialized";
@@ -11,7 +12,7 @@ const List<String> kCorruptedBuildErrors = [
"Critical error", "Critical error",
"when 0 bytes remain", "when 0 bytes remain",
"Pak chunk signature verification failed!", "Pak chunk signature verification failed!",
"Couldn't find pak signature file" "LogWindows:Error: Fatal error!"
]; ];
const List<String> kCannotConnectErrors = [ const List<String> kCannotConnectErrors = [
"port 3551 failed: Connection refused", "port 3551 failed: Connection refused",
@@ -21,3 +22,5 @@ const List<String> kCannotConnectErrors = [
"UOnlineAccountCommon::ForceLogout" "UOnlineAccountCommon::ForceLogout"
]; ];
const String kGameFinishedLine = "PlayersLeft: 1"; const String kGameFinishedLine = "PlayersLeft: 1";
const String kDisplayLine = "Display";
const String kDisplayInitializedLine = "Initialized";

View File

@@ -5,38 +5,50 @@ 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) for(final child in directory.listSync()) {
.firstWhere((element) => path.basename(element.path) == name); if(child is Directory) {
return File(result.path); if(!path.basename(child.path).startsWith("\.")) {
final result = findFile(child, name);
if(result != null) {
return result;
}
}
}else if(child is File) {
if(path.basename(child.path) == name) {
return child;
}
}
}
return null;
}catch(_){ }catch(_){
return null; return null;
} }
} }
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");
} }

View File

@@ -2,7 +2,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
extension ProcessExtension on Process { extension ProcessExtension on Process {
Stream<String> get stdOutput => this.stdout.expand((event) => utf8.decode(event).split("\n")); Stream<String> get stdOutput => this.stdout.expand((event) => utf8.decode(event, allowMalformed: true).split("\n"));
Stream<String> get stdError => this.stderr.expand((event) => utf8.decode(event).split("\n")); Stream<String> get stdError => this.stderr.expand((event) => utf8.decode(event, allowMalformed: true).split("\n"));
} }

View File

@@ -0,0 +1,10 @@
enum InjectableDll {
console,
auth,
gameServer,
memoryLeak
}
extension InjectableDllVersionAware on InjectableDll {
bool get isVersionDependent => this == InjectableDll.gameServer;
}

View File

@@ -1,27 +1,31 @@
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
}); });
} }
class FortniteBuildDownloadProgress { class FortniteBuildDownloadProgress {
final double progress; final double progress;
final int? minutesLeft; final int? timeLeft;
final bool extracting; final bool extracting;
final int speed;
FortniteBuildDownloadProgress({ FortniteBuildDownloadProgress({
required this.progress, required this.progress,
required this.extracting, required this.extracting,
this.minutesLeft, required this.timeLeft,
required this.speed
}); });
} }

View 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
};
}

Some files were not shown because too many files have changed in this diff Show More