9.0.4
@@ -52,7 +52,7 @@ void main(List<String> args) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stdout.writeln("Launching game...");
|
stdout.writeln("Launching game...");
|
||||||
var executable = await version.executable;
|
var executable = version.gameExecutable;
|
||||||
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.executable;
|
var executable = await version.gameExecutable;
|
||||||
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?");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Future<void> downloadRequiredDLLs() async {
|
|||||||
await memoryFixDll.writeAsBytes(response.bodyBytes);
|
await memoryFixDll.writeAsBytes(response.bodyBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!authenticatorDirectory.existsSync()){
|
if(!backendDirectory.existsSync()){
|
||||||
var response = await http.get(Uri.parse(_embeddedConfigDownload));
|
var response = await http.get(Uri.parse(_embeddedConfigDownload));
|
||||||
if(response.statusCode != 200){
|
if(response.statusCode != 200){
|
||||||
throw Exception("Cannot download embedded server config");
|
throw Exception("Cannot download embedded server config");
|
||||||
@@ -50,6 +50,6 @@ Future<void> downloadRequiredDLLs() async {
|
|||||||
|
|
||||||
var tempZip = File("${tempDirectory.path}/reboot_config.zip");
|
var tempZip = File("${tempDirectory.path}/reboot_config.zip");
|
||||||
await tempZip.writeAsBytes(response.bodyBytes);
|
await tempZip.writeAsBytes(response.bodyBytes);
|
||||||
await extractFileToDisk(tempZip.path, authenticatorDirectory.path);
|
await extractFileToDisk(tempZip.path, backendDirectory.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
import 'package:reboot_common/src/util/authenticator.dart' as server;
|
import 'package:reboot_common/src/util/backend.dart' as server;
|
||||||
|
|
||||||
Future<bool> startServerCli(String? host, int? port, ServerType type) async {
|
Future<bool> startServerCli(String? host, int? port, ServerType type) async {
|
||||||
stdout.writeln("Starting backend server...");
|
stdout.writeln("Starting backend server...");
|
||||||
switch(type){
|
switch(type){
|
||||||
case ServerType.local:
|
case ServerType.local:
|
||||||
var result = await pingAuthenticator(host ?? kDefaultAuthenticatorHost, port ?? kDefaultAuthenticatorPort);
|
var result = await pingBackend(host ?? kDefaultBackendHost, port ?? kDefaultBackendPort);
|
||||||
if(result == null){
|
if(result == null){
|
||||||
throw Exception("Local backend server is not running");
|
throw Exception("Local backend server is not running");
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,8 @@ Future<bool> startServerCli(String? host, int? port, ServerType type) async {
|
|||||||
return true;
|
return true;
|
||||||
case ServerType.embedded:
|
case ServerType.embedded:
|
||||||
stdout.writeln("Starting an embedded server...");
|
stdout.writeln("Starting an embedded server...");
|
||||||
await server.startEmbeddedAuthenticator(false);
|
await server.startEmbeddedBackend(false);
|
||||||
var result = await pingAuthenticator(host ?? kDefaultAuthenticatorHost, port ?? kDefaultAuthenticatorPort);
|
var result = await pingBackend(host ?? kDefaultBackendHost, port ?? kDefaultBackendPort);
|
||||||
if(result == null){
|
if(result == null){
|
||||||
throw Exception("Cannot start embedded server");
|
throw Exception("Cannot start embedded server");
|
||||||
}
|
}
|
||||||
@@ -39,12 +39,12 @@ Future<bool> startServerCli(String? host, int? port, ServerType type) async {
|
|||||||
|
|
||||||
Future<HttpServer?> _changeReverseProxyState(String host, int port) async {
|
Future<HttpServer?> _changeReverseProxyState(String host, int port) async {
|
||||||
try{
|
try{
|
||||||
var uri = await pingAuthenticator(host, port);
|
var uri = await pingBackend(host, port);
|
||||||
if(uri == null){
|
if(uri == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await server.startRemoteAuthenticatorProxy(uri);
|
return await server.startRemoteBackendProxy(uri);
|
||||||
}catch(error){
|
}catch(error){
|
||||||
throw Exception("Cannot start reverse proxy");
|
throw Exception("Cannot start reverse proxy");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export 'package:reboot_common/src/constant/authenticator.dart';
|
export 'package:reboot_common/src/constant/backend.dart';
|
||||||
export 'package:reboot_common/src/constant/game.dart';
|
export 'package:reboot_common/src/constant/game.dart';
|
||||||
export 'package:reboot_common/src/constant/matchmaker.dart';
|
export 'package:reboot_common/src/constant/matchmaker.dart';
|
||||||
export 'package:reboot_common/src/constant/supabase.dart';
|
export 'package:reboot_common/src/constant/supabase.dart';
|
||||||
@@ -9,8 +9,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/process.dart';
|
export 'package:reboot_common/src/util/backend.dart';
|
||||||
export 'package:reboot_common/src/util/authenticator.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/matchmaker.dart';
|
export 'package:reboot_common/src/util/matchmaker.dart';
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
const String kDefaultAuthenticatorHost = "127.0.0.1";
|
|
||||||
const int kDefaultAuthenticatorPort = 3551;
|
|
||||||
2
common/lib/src/constant/backend.dart
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
const String kDefaultBackendHost = "127.0.0.1";
|
||||||
|
const int kDefaultBackendPort = 3551;
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
const String kDefaultPlayerName = "Player";
|
const String kDefaultPlayerName = "Player";
|
||||||
const String kDefaultGameServerHost = "127.0.0.1";
|
const String kDefaultGameServerHost = "127.0.0.1";
|
||||||
const String kDefaultGameServerPort = "7777";
|
const String kDefaultGameServerPort = "7777";
|
||||||
const String kConsoleLine = "Region ";
|
const String kInitializedLine = "Game Engine Initialized";
|
||||||
|
const List<String> kLoggedInLines = [
|
||||||
|
"[UOnlineAccountCommon::ContinueLoggingIn]",
|
||||||
|
"(Completed)"
|
||||||
|
];
|
||||||
const String kShutdownLine = "FOnlineSubsystemGoogleCommon::Shutdown()";
|
const String kShutdownLine = "FOnlineSubsystemGoogleCommon::Shutdown()";
|
||||||
const List<String> kCorruptedBuildErrors = [
|
const List<String> kCorruptedBuildErrors = [
|
||||||
|
"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"
|
||||||
];
|
];
|
||||||
const List<String> kCannotConnectErrors = [
|
const List<String> kCannotConnectErrors = [
|
||||||
"port 3551 failed: Connection refused",
|
"port 3551 failed: Connection refused",
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ class FortniteBuildDownloadProgress {
|
|||||||
final int? minutesLeft;
|
final int? minutesLeft;
|
||||||
final bool extracting;
|
final bool extracting;
|
||||||
|
|
||||||
FortniteBuildDownloadProgress(this.progress, this.minutesLeft, this.extracting);
|
FortniteBuildDownloadProgress({
|
||||||
|
required this.progress,
|
||||||
|
required this.extracting,
|
||||||
|
this.minutesLeft,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class FortniteBuildDownloadOptions {
|
class FortniteBuildDownloadOptions {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ class GameInstance {
|
|||||||
final int gamePid;
|
final int gamePid;
|
||||||
final int? launcherPid;
|
final int? launcherPid;
|
||||||
final int? eacPid;
|
final int? eacPid;
|
||||||
int? observerPid;
|
|
||||||
bool hosting;
|
bool hosting;
|
||||||
bool launched;
|
bool launched;
|
||||||
bool tokenError;
|
bool tokenError;
|
||||||
@@ -29,9 +28,18 @@ class GameInstance {
|
|||||||
if(eacPid != null) {
|
if(eacPid != null) {
|
||||||
Process.killPid(eacPid!, ProcessSignal.sigabrt);
|
Process.killPid(eacPid!, ProcessSignal.sigabrt);
|
||||||
}
|
}
|
||||||
if(observerPid != null) {
|
}
|
||||||
Process.killPid(observerPid!, ProcessSignal.sigabrt);
|
|
||||||
|
bool get nestedHosting {
|
||||||
|
GameInstance? child = this;
|
||||||
|
while(child != null) {
|
||||||
|
if(child.hosting) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = child.child;
|
||||||
}
|
}
|
||||||
child?.kill();
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
class Win32Process {
|
|
||||||
final int pid;
|
|
||||||
final Stream<String> stdOutput;
|
|
||||||
final Stream<String> errorOutput;
|
|
||||||
|
|
||||||
Win32Process({
|
|
||||||
required this.pid,
|
|
||||||
required this.stdOutput,
|
|
||||||
required this.errorOutput
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class PrimitiveWin32Process {
|
|
||||||
final int pid;
|
|
||||||
final int stdOutputHandle;
|
|
||||||
final int errorOutputHandle;
|
|
||||||
|
|
||||||
PrimitiveWin32Process({
|
|
||||||
required this.pid,
|
|
||||||
required this.stdOutputHandle,
|
|
||||||
required this.errorOutputHandle
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -24,4 +24,6 @@ enum ServerResultType {
|
|||||||
pingError;
|
pingError;
|
||||||
|
|
||||||
bool get isError => name.contains("Error");
|
bool get isError => name.contains("Error");
|
||||||
|
|
||||||
|
bool get isSuccess => this == ServerResultType.startSuccess || this == ServerResultType.stopSuccess;
|
||||||
}
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:reboot_common/common.dart';
|
|
||||||
import 'package:shelf/shelf_io.dart';
|
|
||||||
import 'package:shelf_proxy/shelf_proxy.dart';
|
|
||||||
|
|
||||||
final authenticatorDirectory = Directory("${assetsDirectory.path}\\authenticator");
|
|
||||||
final authenticatorStartExecutable = File("${authenticatorDirectory.path}\\lawinserver.exe");
|
|
||||||
|
|
||||||
Future<Win32Process> startEmbeddedAuthenticator(bool detached) async => startProcess(
|
|
||||||
executable: authenticatorStartExecutable,
|
|
||||||
window: detached,
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<HttpServer> startRemoteAuthenticatorProxy(Uri uri) async => await serve(proxyHandler(uri), kDefaultAuthenticatorHost, kDefaultAuthenticatorPort);
|
|
||||||
|
|
||||||
Future<bool> isAuthenticatorPortFree() async => await pingAuthenticator(kDefaultAuthenticatorHost, kDefaultAuthenticatorPort) == null;
|
|
||||||
|
|
||||||
Future<bool> freeAuthenticatorPort() async {
|
|
||||||
await killProcessByPort(kDefaultAuthenticatorPort);
|
|
||||||
final standardResult = await isAuthenticatorPortFree();
|
|
||||||
if(standardResult) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Uri?> pingAuthenticator(String host, int port, [bool https=false]) async {
|
|
||||||
var hostName = _getHostName(host);
|
|
||||||
var declaredScheme = _getScheme(host);
|
|
||||||
try{
|
|
||||||
var uri = Uri(
|
|
||||||
scheme: declaredScheme ?? (https ? "https" : "http"),
|
|
||||||
host: hostName,
|
|
||||||
port: port,
|
|
||||||
path: "unknown"
|
|
||||||
);
|
|
||||||
var client = HttpClient()
|
|
||||||
..connectionTimeout = const Duration(seconds: 5);
|
|
||||||
var request = await client.getUrl(uri);
|
|
||||||
var response = await request.close();
|
|
||||||
return response.statusCode == 200 || response.statusCode == 404 ? uri : null;
|
|
||||||
}catch(_){
|
|
||||||
return https || declaredScheme != null || isLocalHost(host) ? null : await pingAuthenticator(host, port, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String? _getHostName(String host) => host.replaceFirst("http://", "").replaceFirst("https://", "");
|
|
||||||
|
|
||||||
String? _getScheme(String host) => host.startsWith("http://") ? "http" : host.startsWith("https://") ? "https" : null;
|
|
||||||
|
|
||||||
@@ -1,24 +1,61 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:ini/ini.dart';
|
import 'package:ini/ini.dart';
|
||||||
import 'package:reboot_common/common.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
|
import 'package:shelf/shelf_io.dart';
|
||||||
|
import 'package:shelf_proxy/shelf_proxy.dart';
|
||||||
import 'package:sync/semaphore.dart';
|
import 'package:sync/semaphore.dart';
|
||||||
|
|
||||||
final matchmakerDirectory = Directory("${assetsDirectory.path}\\matchmaker");
|
final Directory backendDirectory = Directory("${assetsDirectory.path}\\backend");
|
||||||
final matchmakerStartExecutable = File("${matchmakerDirectory.path}\\fortmatchmaker.exe");
|
final File backendStartExecutable = File("${backendDirectory.path}\\lawinserver.exe");
|
||||||
final matchmakerKillExecutable = File("${authenticatorDirectory.path}\\kill.bat");
|
final File matchmakerConfigFile = File("${backendDirectory.path}\\Config\\config.ini");
|
||||||
final matchmakerConfigFile = File("${authenticatorDirectory.path}\\Config\\config.ini");
|
final Semaphore _semaphore = Semaphore();
|
||||||
String? _lastIp;
|
String? _lastIp;
|
||||||
String? _lastPort;
|
String? _lastPort;
|
||||||
Semaphore _semaphore = Semaphore();
|
|
||||||
|
|
||||||
Future<Win32Process> startEmbeddedMatchmaker(bool detached) async => startProcess(
|
Future<Process> startEmbeddedBackend(bool detached) async => startProcess(
|
||||||
executable: matchmakerStartExecutable,
|
executable: backendStartExecutable,
|
||||||
window: detached,
|
window: detached,
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Future<HttpServer> startRemoteBackendProxy(Uri uri) async => await serve(proxyHandler(uri), kDefaultBackendHost, kDefaultBackendPort);
|
||||||
|
|
||||||
|
Future<bool> isBackendPortFree() async => await pingBackend(kDefaultBackendHost, kDefaultBackendPort) == null;
|
||||||
|
|
||||||
|
Future<bool> freeBackendPort() async {
|
||||||
|
await killProcessByPort(kDefaultBackendPort);
|
||||||
|
final standardResult = await isBackendPortFree();
|
||||||
|
if(standardResult) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Uri?> pingBackend(String host, int port, [bool https=false]) async {
|
||||||
|
var hostName = _getHostName(host);
|
||||||
|
var declaredScheme = _getScheme(host);
|
||||||
|
try{
|
||||||
|
var uri = Uri(
|
||||||
|
scheme: declaredScheme ?? (https ? "https" : "http"),
|
||||||
|
host: hostName,
|
||||||
|
port: port,
|
||||||
|
path: "unknown"
|
||||||
|
);
|
||||||
|
var client = HttpClient()
|
||||||
|
..connectionTimeout = const Duration(seconds: 5);
|
||||||
|
var request = await client.getUrl(uri);
|
||||||
|
var response = await request.close();
|
||||||
|
return response.statusCode == 200 || response.statusCode == 404 ? uri : null;
|
||||||
|
}catch(_){
|
||||||
|
return https || declaredScheme != null || isLocalHost(host) ? null : await pingBackend(host, port, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String? _getHostName(String host) => host.replaceFirst("http://", "").replaceFirst("https://", "");
|
||||||
|
|
||||||
|
String? _getScheme(String host) => host.startsWith("http://") ? "http" : host.startsWith("https://") ? "https" : null;
|
||||||
|
|
||||||
Stream<String?> watchMatchmakingIp() async* {
|
Stream<String?> watchMatchmakingIp() async* {
|
||||||
if(!matchmakerConfigFile.existsSync()){
|
if(!matchmakerConfigFile.existsSync()){
|
||||||
return;
|
return;
|
||||||
@@ -99,7 +136,7 @@ Future<Uri?> pingMatchmaker(String host, int port, [bool wss=false]) async {
|
|||||||
var completer = Completer<bool>();
|
var completer = Completer<bool>();
|
||||||
var socket = await WebSocket.connect(uri.toString());
|
var socket = await WebSocket.connect(uri.toString());
|
||||||
socket.listen(
|
socket.listen(
|
||||||
(data) {
|
(data) {
|
||||||
if(!completer.isCompleted) {
|
if(!completer.isCompleted) {
|
||||||
completer.complete(true);
|
completer.complete(true);
|
||||||
}
|
}
|
||||||
@@ -125,20 +162,4 @@ Future<Uri?> pingMatchmaker(String host, int port, [bool wss=false]) async {
|
|||||||
|
|
||||||
String? _getHostName(String host) => host.replaceFirst("ws://", "").replaceFirst("wss://", "");
|
String? _getHostName(String host) => host.replaceFirst("ws://", "").replaceFirst("wss://", "");
|
||||||
|
|
||||||
String? _getScheme(String host) => host.startsWith("ws://") ? "ws" : host.startsWith("wss://") ? "wss" : null;
|
String? _getScheme(String host) => host.startsWith("ws://") ? "ws" : host.startsWith("wss://") ? "wss" : null;
|
||||||
|
|
||||||
extension StringExtension on String {
|
|
||||||
bool get isBlank {
|
|
||||||
if(isEmpty) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(var char in this.split("")) {
|
|
||||||
if(char != " ") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,8 +25,11 @@ Dio _buildDioInstance() {
|
|||||||
|
|
||||||
final String _archiveSourceUrl = "https://raw.githubusercontent.com/simplyblk/Fortnitebuilds/main/README.md";
|
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 _manifestSourceUrl = "https://manifest.fnbuilds.services";
|
const String _manifestSourceUrl = "http://manifest.simplyblk.xyz";
|
||||||
const int _maxDownloadErrors = 30;
|
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 _genericError = "The build downloader is not working correctly";
|
||||||
|
const int _maxErrors = 100;
|
||||||
|
|
||||||
Future<List<FortniteBuild>> fetchBuilds(ignored) async {
|
Future<List<FortniteBuild>> fetchBuilds(ignored) async {
|
||||||
(_dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () =>
|
(_dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () =>
|
||||||
@@ -35,7 +38,7 @@ Future<List<FortniteBuild>> fetchBuilds(ignored) async {
|
|||||||
(X509Certificate cert, String host, int port) => true;
|
(X509Certificate cert, String host, int port) => true;
|
||||||
|
|
||||||
final results = await Future.wait([_fetchManifestBuilds(), _fetchArchiveBuilds()]);
|
final results = await Future.wait([_fetchManifestBuilds(), _fetchArchiveBuilds()]);
|
||||||
final data = <FortniteBuild>[];
|
final data = <FortniteBuild>[];
|
||||||
for(final result in results) {
|
for(final result in results) {
|
||||||
data.addAll(result);
|
data.addAll(result);
|
||||||
}
|
}
|
||||||
@@ -45,7 +48,15 @@ Future<List<FortniteBuild>> fetchBuilds(ignored) async {
|
|||||||
|
|
||||||
Future<List<FortniteBuild>> _fetchManifestBuilds() async {
|
Future<List<FortniteBuild>> _fetchManifestBuilds() async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.get<String>("$_manifestSourceUrl/versions.json");
|
final response = await _dio.get<String>(
|
||||||
|
"$_manifestSourceUrl/versions.json",
|
||||||
|
options: Options(
|
||||||
|
headers: {
|
||||||
|
"Accept-Encoding": "*",
|
||||||
|
"Cookie": "_c_t_c=1"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
final body = response.data;
|
final body = response.data;
|
||||||
return jsonDecode(body!).map((version) {
|
return jsonDecode(body!).map((version) {
|
||||||
final nameParts = version.split("-");
|
final nameParts = version.split("-");
|
||||||
@@ -131,7 +142,14 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
delete(outputDir);
|
delete(outputDir);
|
||||||
break;
|
break;
|
||||||
case FortniteBuildSource.manifest:
|
case FortniteBuildSource.manifest:
|
||||||
final response = await _dio.get<String>(options.build.link);
|
final response = await _dio.get<String>(
|
||||||
|
options.build.link,
|
||||||
|
options: Options(
|
||||||
|
headers: {
|
||||||
|
"Cookie": "_c_t_c=1"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
final manifest = FortniteBuildManifestFile.fromJson(jsonDecode(response.data!));
|
final manifest = FortniteBuildManifestFile.fromJson(jsonDecode(response.data!));
|
||||||
|
|
||||||
final totalBytes = manifest.size;
|
final totalBytes = manifest.size;
|
||||||
@@ -171,7 +189,8 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
options: Options(
|
options: Options(
|
||||||
responseType: ResponseType.bytes,
|
responseType: ResponseType.bytes,
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Encoding": "gzip"
|
"Accept-Encoding": "gzip",
|
||||||
|
"Cookie": "_c_t_c=1"
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -201,24 +220,23 @@ Future<void> downloadArchiveBuild(FortniteBuildDownloadOptions options) async {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
await Future.any([stopped.future, Future.wait(writers)]);
|
await Future.any([stopped.future, Future.wait(writers)]);
|
||||||
options.port.send(FortniteBuildDownloadProgress(100, 0, true));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}catch(error, stackTrace) {
|
}catch(error) {
|
||||||
options.port.send("$error\n$stackTrace");
|
_onError(error, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Response> _downloadArchive(FortniteBuildDownloadOptions options, File tempFile, int startTime, [int? byteStart = null, int errorsCount = 0]) async {
|
Future<void> _downloadArchive(FortniteBuildDownloadOptions options, File tempFile, int startTime, [int? byteStart = null, int errorsCount = 0]) async {
|
||||||
var received = byteStart ?? 0;
|
var received = byteStart ?? 0;
|
||||||
try {
|
try {
|
||||||
return await _dio.download(
|
await _dio.download(
|
||||||
options.build.link,
|
options.build.link,
|
||||||
tempFile.path,
|
tempFile.path,
|
||||||
onReceiveProgress: (data, length) {
|
onReceiveProgress: (data, length) {
|
||||||
received = data;
|
received = data;
|
||||||
final percentage = (received / length) * 100;
|
final percentage = (received / length) * 100;
|
||||||
_onProgress(startTime, DateTime.now().millisecondsSinceEpoch, percentage, false, options);
|
_onProgress(startTime, percentage < 1 ? null : DateTime.now().millisecondsSinceEpoch, percentage, false, options);
|
||||||
},
|
},
|
||||||
deleteOnError: false,
|
deleteOnError: false,
|
||||||
options: Options(
|
options: Options(
|
||||||
@@ -228,10 +246,14 @@ Future<Response> _downloadArchive(FortniteBuildDownloadOptions options, File tem
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(statusCode == 403 || statusCode == 503) {
|
if(statusCode == 403 || statusCode == 503) {
|
||||||
throw Exception("The connection was denied: your firewall might be blocking the download");
|
throw _deniedConnectionError;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("The build downloader is not available right now");
|
if(statusCode == 404) {
|
||||||
|
throw _unavailableError;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw _genericError;
|
||||||
},
|
},
|
||||||
headers: byteStart == null || byteStart <= 0 ? {
|
headers: byteStart == null || byteStart <= 0 ? {
|
||||||
"Cookie": "_c_t_c=1"
|
"Cookie": "_c_t_c=1"
|
||||||
@@ -242,17 +264,18 @@ Future<Response> _downloadArchive(FortniteBuildDownloadOptions options, File tem
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}catch(error) {
|
}catch(error) {
|
||||||
if(errorsCount >= _maxDownloadErrors) {
|
if(errorsCount > _maxErrors || error.toString().contains(_deniedConnectionError) || error.toString().contains(_unavailableError)) {
|
||||||
throw error;
|
_onError(error, options);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _downloadArchive(options, tempFile, startTime, received, errorsCount + 1);
|
await _downloadArchive(options, tempFile, startTime, received, errorsCount + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
|
Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File tempFile, FortniteBuildDownloadOptions options) async {
|
||||||
final startTime = DateTime.now().millisecondsSinceEpoch;
|
final startTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
Win32Process? process;
|
Process? process;
|
||||||
switch (extension.toLowerCase()) {
|
switch (extension.toLowerCase()) {
|
||||||
case ".zip":
|
case ".zip":
|
||||||
final sevenZip = File("${assetsDirectory.path}\\build\\7zip.exe");
|
final sevenZip = File("${assetsDirectory.path}\\build\\7zip.exe");
|
||||||
@@ -271,10 +294,10 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
process.stdOutput.listen((data) {
|
process.stdOutput.listen((data) {
|
||||||
print(data);
|
|
||||||
final now = DateTime.now().millisecondsSinceEpoch;
|
final now = DateTime.now().millisecondsSinceEpoch;
|
||||||
if(data == "Everything is Ok") {
|
if(data.toLowerCase().contains("everything is ok")) {
|
||||||
options.port.send(FortniteBuildDownloadProgress(100, 0, true));
|
_onProgress(startTime, now, 100, true, options);
|
||||||
|
process?.kill(ProcessSignal.sigabrt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,6 +309,11 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
final percentage = int.parse(element.substring(0, element.length - 1)).toDouble();
|
final percentage = int.parse(element.substring(0, element.length - 1)).toDouble();
|
||||||
_onProgress(startTime, now, percentage, true, options);
|
_onProgress(startTime, now, percentage, true, options);
|
||||||
});
|
});
|
||||||
|
process.stdError.listen((data) {
|
||||||
|
if(!data.isBlank) {
|
||||||
|
_onError(data, options);
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case ".rar":
|
case ".rar":
|
||||||
final winrar = File("${assetsDirectory.path}\\build\\winrar.exe");
|
final winrar = File("${assetsDirectory.path}\\build\\winrar.exe");
|
||||||
@@ -298,17 +326,17 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
args: [
|
args: [
|
||||||
"x",
|
"x",
|
||||||
"-o+",
|
"-o+",
|
||||||
tempFile.path,
|
'"${tempFile.path}"',
|
||||||
"*.*",
|
"*.*",
|
||||||
options.destination.path
|
'"${options.destination.path}"'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
process.stdOutput.listen((data) {
|
process.stdOutput.listen((data) {
|
||||||
print(data);
|
|
||||||
final now = DateTime.now().millisecondsSinceEpoch;
|
final now = DateTime.now().millisecondsSinceEpoch;
|
||||||
data.replaceAll("\r", "").replaceAll("\b", "").trim();
|
data = data.replaceAll("\r", "").replaceAll("\b", "").trim();
|
||||||
if(data == "All OK") {
|
if(data == "All OK") {
|
||||||
options.port.send(FortniteBuildDownloadProgress(100, 0, true));
|
_onProgress(startTime, now, 100, true, options);
|
||||||
|
process?.kill(ProcessSignal.sigabrt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +348,11 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
final percentage = int.parse(element).toDouble();
|
final percentage = int.parse(element).toDouble();
|
||||||
_onProgress(startTime, now, percentage, true, options);
|
_onProgress(startTime, now, percentage, true, options);
|
||||||
});
|
});
|
||||||
process.errorOutput.listen((data) => options.port.send(data));
|
process.stdError.listen((data) {
|
||||||
|
if(!data.isBlank) {
|
||||||
|
_onError(data, options);
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError("Unexpected file extension: $extension}");
|
throw ArgumentError("Unexpected file extension: $extension}");
|
||||||
@@ -329,17 +361,31 @@ Future<void> _extractArchive(Completer<dynamic> stopped, String extension, File
|
|||||||
await Future.any([stopped.future, watchProcess(process.pid)]);
|
await Future.any([stopped.future, watchProcess(process.pid)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onProgress(int startTime, int now, double percentage, bool extracting, FortniteBuildDownloadOptions options) {
|
void _onProgress(int startTime, int? now, double percentage, bool extracting, FortniteBuildDownloadOptions options) {
|
||||||
if(percentage == 0) {
|
if(percentage == 0) {
|
||||||
options.port.send(FortniteBuildDownloadProgress(percentage, null, extracting));
|
options.port.send(FortniteBuildDownloadProgress(
|
||||||
|
progress: percentage,
|
||||||
|
extracting: extracting
|
||||||
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final msLeft = startTime + (now - startTime) * 100 / percentage - now;
|
final msLeft = now == null ? null : startTime + (now - startTime) * 100 / percentage - now;
|
||||||
final minutesLeft = (msLeft / 1000 / 60).round();
|
final minutesLeft = msLeft == null ? null : (msLeft / 1000 / 60).round();
|
||||||
options.port.send(FortniteBuildDownloadProgress(percentage, minutesLeft, extracting));
|
options.port.send(FortniteBuildDownloadProgress(
|
||||||
|
progress: percentage,
|
||||||
|
extracting: extracting,
|
||||||
|
minutesLeft: minutesLeft
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onError(Object? error, FortniteBuildDownloadOptions options) {
|
||||||
|
if(error != null) {
|
||||||
|
options.port.send(error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Completer<dynamic> _setupLifecycle(FortniteBuildDownloadOptions options) {
|
Completer<dynamic> _setupLifecycle(FortniteBuildDownloadOptions options) {
|
||||||
var stopped = Completer();
|
var stopped = Completer();
|
||||||
var lifecyclePort = ReceivePort();
|
var lifecyclePort = ReceivePort();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import 'package:reboot_common/common.dart';
|
|||||||
bool _watcher = false;
|
bool _watcher = false;
|
||||||
final File rebootDllFile = File("${assetsDirectory.path}\\dlls\\reboot.dll");
|
final File rebootDllFile = File("${assetsDirectory.path}\\dlls\\reboot.dll");
|
||||||
const String kRebootDownloadUrl =
|
const String kRebootDownloadUrl =
|
||||||
"https://nightly.link/Milxnor/Project-Reboot-3.0/workflows/msbuild/master/Release.zip";
|
"http://nightly.link/Milxnor/Project-Reboot-3.0/workflows/msbuild/master/Release.zip";
|
||||||
|
|
||||||
Future<bool> hasRebootDllUpdate(int? lastUpdateMs, {int hours = 24, bool force = false}) async {
|
Future<bool> hasRebootDllUpdate(int? lastUpdateMs, {int hours = 24, bool force = false}) async {
|
||||||
final lastUpdate = await _getLastUpdate(lastUpdateMs);
|
final lastUpdate = await _getLastUpdate(lastUpdateMs);
|
||||||
@@ -18,7 +18,7 @@ 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 {
|
||||||
final response = await http.get(Uri.parse("https://github.com/Auties00/reboot_launcher/tree/master/gui/assets/dlls/$name"));
|
final response = await http.get(Uri.parse("https://github.com/Auties00/reboot_launcher/raw/master/gui/assets/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}");
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,6 @@ Stream<String> watchDlls() async* {
|
|||||||
|
|
||||||
_watcher = true;
|
_watcher = true;
|
||||||
await for(final event in rebootDllFile.parent.watch(events: FileSystemEvent.delete | FileSystemEvent.move)) {
|
await for(final event in rebootDllFile.parent.watch(events: FileSystemEvent.delete | FileSystemEvent.move)) {
|
||||||
print(event);
|
|
||||||
if (event.path.endsWith(".dll")) {
|
if (event.path.endsWith(".dll")) {
|
||||||
yield event.path;
|
yield event.path;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,27 +31,36 @@ Future<bool> _patch(File file, Uint8List original, Uint8List patched) async {
|
|||||||
|
|
||||||
var read = await file.readAsBytes();
|
var read = await file.readAsBytes();
|
||||||
var length = await file.length();
|
var length = await file.length();
|
||||||
var offset = 0;
|
var readOffset = 0;
|
||||||
var counter = 0;
|
var patchOffset = -1;
|
||||||
while(offset < length){
|
var patchCount = 0;
|
||||||
if(read[offset] == original[counter]){
|
while(readOffset < length){
|
||||||
counter++;
|
if(read[readOffset] == original[patchCount]){
|
||||||
}else {
|
if(patchOffset == -1) {
|
||||||
counter = 0;
|
patchOffset = readOffset;
|
||||||
}
|
|
||||||
|
|
||||||
offset++;
|
|
||||||
if(counter == original.length){
|
|
||||||
for(var index = 0; index < patched.length; index++){
|
|
||||||
read[offset - counter + index] = patched[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await file.writeAsBytes(read, mode: FileMode.write);
|
if(++patchCount == original.length) {
|
||||||
return true;
|
break;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
patchOffset = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
print("Offset: $patchOffset");
|
||||||
|
if(patchOffset == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < patched.length; i++) {
|
||||||
|
read[patchOffset + i] = patched[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
await file.writeAsBytes(read, flush: true);
|
||||||
|
return true;
|
||||||
}catch(_){
|
}catch(_){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,8 +52,10 @@ extension FortniteVersionExtension on FortniteVersion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> get executable async {
|
File? get gameExecutable => findExecutable(location, "FortniteClient-Win64-Shipping.exe");
|
||||||
var result = findExecutable(location, "FortniteClient-Win64-Shipping-Reboot.exe");
|
|
||||||
|
Future<File?> get headlessGameExecutable async {
|
||||||
|
var result = findExecutable(location, "FortniteClient-Win64-Shipping-Headless.exe");
|
||||||
if(result != null) {
|
if(result != null) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -63,12 +65,9 @@ extension FortniteVersionExtension on FortniteVersion {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var output = File("${original.parent.path}\\FortniteClient-Win64-Shipping-Reboot.exe");
|
var output = File("${original.parent.path}\\FortniteClient-Win64-Shipping-Headless.exe");
|
||||||
await original.copy(output.path);
|
await original.copy(output.path);
|
||||||
await Future.wait([
|
await Isolate.run(() => patchHeadless(output));
|
||||||
Isolate.run(() => patchMatchmaking(output)),
|
|
||||||
Isolate.run(() => patchHeadless(output)),
|
|
||||||
]);
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import 'dart:ffi';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:reboot_common/src/model/process.dart';
|
import 'package:reboot_common/common.dart';
|
||||||
|
import 'package:sync/semaphore.dart';
|
||||||
import 'package:win32/win32.dart';
|
import 'package:win32/win32.dart';
|
||||||
|
|
||||||
import '../constant/game.dart';
|
|
||||||
|
|
||||||
final _ntdll = DynamicLibrary.open('ntdll.dll');
|
final _ntdll = DynamicLibrary.open('ntdll.dll');
|
||||||
final _kernel32 = DynamicLibrary.open('kernel32.dll');
|
final _kernel32 = DynamicLibrary.open('kernel32.dll');
|
||||||
final _CreateRemoteThread = _kernel32.lookupFunction<
|
final _CreateRemoteThread = _kernel32.lookupFunction<
|
||||||
@@ -90,139 +90,53 @@ Future<void> injectDll(int pid, String dll) async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startProcess(_ProcessParameters params) {
|
Future<Process> startProcess({required File executable, List<String>? args, bool wrapProcess = true, bool window = false, String? name}) async {
|
||||||
final args = params.args;
|
final argsOrEmpty = args ?? [];
|
||||||
final port = params.port;
|
if(wrapProcess) {
|
||||||
final concatenatedArgs = args == null ? "" : " ${args.join(" ")}";
|
final tempScriptDirectory = await tempDirectory.createTemp("reboot_launcher_process");
|
||||||
final command = params.window ? 'cmd.exe /k ""${params.executable.path}"$concatenatedArgs"' : '"${params.executable.path}"$concatenatedArgs';
|
final tempScriptFile = File("${tempScriptDirectory.path}/process.bat");
|
||||||
print(command);
|
final command = window ? 'cmd.exe /k ""${executable.path}" ${argsOrEmpty.join(" ")}"' : '"${executable.path}" ${argsOrEmpty.join(" ")}';
|
||||||
final processInfo = calloc<PROCESS_INFORMATION>();
|
await tempScriptFile.writeAsString(command, flush: true);
|
||||||
final lpStartupInfo = calloc<STARTUPINFO>();
|
final process = await Process.start(
|
||||||
lpStartupInfo.ref.cb = sizeOf<STARTUPINFO>();
|
tempScriptFile.path,
|
||||||
lpStartupInfo.ref.dwFlags |= STARTF_USESTDHANDLES;
|
[],
|
||||||
final securityAttributes = calloc<SECURITY_ATTRIBUTES>();
|
workingDirectory: executable.parent.path,
|
||||||
securityAttributes.ref.nLength = sizeOf<SECURITY_ATTRIBUTES>();
|
mode: window ? ProcessStartMode.detachedWithStdio : ProcessStartMode.normal,
|
||||||
securityAttributes.ref.bInheritHandle = TRUE;
|
runInShell: window
|
||||||
final hStdOutRead = calloc<HANDLE>();
|
);
|
||||||
final hStdOutWrite = calloc<HANDLE>();
|
return _withLogger(name, executable, process, window);
|
||||||
final hStdErrRead = calloc<HANDLE>();
|
|
||||||
final hStdErrWrite = calloc<HANDLE>();
|
|
||||||
if (CreatePipe(hStdOutRead, hStdOutWrite, securityAttributes, 0) == 0 || CreatePipe(hStdErrRead, hStdErrWrite, securityAttributes, 0) == 0) {
|
|
||||||
final error = GetLastError();
|
|
||||||
port.send("Cannot create process pipe: $error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SetHandleInformation(hStdOutRead.value, HANDLE_FLAG_INHERIT, 0) == 0 || SetHandleInformation(hStdErrRead.value, HANDLE_FLAG_INHERIT, 0) == 0) {
|
|
||||||
final error = GetLastError();
|
|
||||||
port.send("Cannot set process pipe information: $error");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lpStartupInfo.ref.hStdOutput = hStdOutWrite.value;
|
final process = await Process.start(
|
||||||
lpStartupInfo.ref.hStdError = hStdErrWrite.value;
|
executable.path,
|
||||||
final success = CreateProcess(
|
args ?? [],
|
||||||
nullptr,
|
workingDirectory: executable.parent.path,
|
||||||
TEXT(command),
|
mode: window ? ProcessStartMode.detachedWithStdio : ProcessStartMode.normal,
|
||||||
nullptr,
|
runInShell: window
|
||||||
nullptr,
|
|
||||||
TRUE,
|
|
||||||
NORMAL_PRIORITY_CLASS | (params.window ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW) | CREATE_NEW_PROCESS_GROUP,
|
|
||||||
nullptr,
|
|
||||||
TEXT(params.executable.parent.path),
|
|
||||||
lpStartupInfo,
|
|
||||||
processInfo
|
|
||||||
);
|
);
|
||||||
if (success == 0) {
|
return _withLogger(name, executable, process, window);
|
||||||
final error = GetLastError();
|
|
||||||
port.send("Cannot start process: $error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(processInfo.ref.hProcess);
|
|
||||||
CloseHandle(processInfo.ref.hThread);
|
|
||||||
CloseHandle(hStdOutWrite.value);
|
|
||||||
CloseHandle(hStdErrWrite.value);
|
|
||||||
final pid = processInfo.ref.dwProcessId;
|
|
||||||
free(lpStartupInfo);
|
|
||||||
free(processInfo);
|
|
||||||
port.send(PrimitiveWin32Process(
|
|
||||||
pid: pid,
|
|
||||||
stdOutputHandle: hStdOutRead.value,
|
|
||||||
errorOutputHandle: hStdErrRead.value
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PipeReaderParams {
|
_ExtendedProcess _withLogger(String? name, File executable, Process process, bool window) {
|
||||||
final int handle;
|
final extendedProcess = _ExtendedProcess(process, true);
|
||||||
final SendPort port;
|
final loggingFile = File("${logsDirectory.path}\\${name ?? path.basenameWithoutExtension(executable.path)}-${DateTime.now().millisecondsSinceEpoch}.log");
|
||||||
|
loggingFile.parent.createSync(recursive: true);
|
||||||
_PipeReaderParams(this.handle, this.port);
|
if(loggingFile.existsSync()) {
|
||||||
}
|
loggingFile.deleteSync();
|
||||||
|
|
||||||
void _pipeToStreamChannelled(_PipeReaderParams params) {
|
|
||||||
final buf = calloc<Uint8>(chunkSize);
|
|
||||||
while(true) {
|
|
||||||
final bytesReadPtr = calloc<Uint32>();
|
|
||||||
final success = ReadFile(params.handle, buf, chunkSize, bytesReadPtr, nullptr);
|
|
||||||
if (success == FALSE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final bytesRead = bytesReadPtr.value;
|
|
||||||
if (bytesRead == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final lines = utf8.decode(buf.asTypedList(bytesRead)).split('\n');
|
|
||||||
for(final line in lines) {
|
|
||||||
params.port.send(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(params.handle);
|
final semaphore = Semaphore(1);
|
||||||
free(buf);
|
void logEvent(String event) async {
|
||||||
Isolate.current.kill();
|
await semaphore.acquire();
|
||||||
}
|
await loggingFile.writeAsString("$event\n", mode: FileMode.append, flush: true);
|
||||||
|
semaphore.release();
|
||||||
Stream<String> _pipeToStream(int pipeHandle) {
|
}
|
||||||
final port = ReceivePort();
|
extendedProcess.stdOutput.listen(logEvent);
|
||||||
Isolate.spawn(
|
extendedProcess.stdError.listen(logEvent);
|
||||||
_pipeToStreamChannelled,
|
if(!window) {
|
||||||
_PipeReaderParams(pipeHandle, port.sendPort)
|
extendedProcess.exitCode.then((value) => logEvent("Process terminated with exit code: $value\n"));
|
||||||
);
|
}
|
||||||
return port.map((event) => event as String);
|
return extendedProcess;
|
||||||
}
|
|
||||||
|
|
||||||
class _ProcessParameters {
|
|
||||||
File executable;
|
|
||||||
List<String>? args;
|
|
||||||
bool window;
|
|
||||||
SendPort port;
|
|
||||||
|
|
||||||
_ProcessParameters(this.executable, this.args, this.window, this.port);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Win32Process> startProcess({required File executable, List<String>? args, bool output = true, bool window = false}) async {
|
|
||||||
final completer = Completer<Win32Process>();
|
|
||||||
final port = ReceivePort();
|
|
||||||
port.listen((message) {
|
|
||||||
if(message is PrimitiveWin32Process) {
|
|
||||||
completer.complete(Win32Process(
|
|
||||||
pid: message.pid,
|
|
||||||
stdOutput: _pipeToStream(message.stdOutputHandle),
|
|
||||||
errorOutput: _pipeToStream(message.errorOutputHandle)
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
completer.completeError(message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Isolate.spawn(
|
|
||||||
_startProcess,
|
|
||||||
_ProcessParameters(executable, args, window, port.sendPort),
|
|
||||||
errorsAreFatal: true
|
|
||||||
);
|
|
||||||
return await completer.future;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final _NtResumeProcess = _ntdll.lookupFunction<Int32 Function(IntPtr hWnd),
|
final _NtResumeProcess = _ntdll.lookupFunction<Int32 Function(IntPtr hWnd),
|
||||||
@@ -247,8 +161,11 @@ bool resume(int pid) {
|
|||||||
|
|
||||||
void _watchProcess(int pid) {
|
void _watchProcess(int pid) {
|
||||||
final processHandle = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
final processHandle = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
||||||
WaitForSingleObject(processHandle, INFINITE);
|
try {
|
||||||
CloseHandle(processHandle);
|
WaitForSingleObject(processHandle, INFINITE);
|
||||||
|
}finally {
|
||||||
|
CloseHandle(processHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> watchProcess(int pid) async {
|
Future<bool> watchProcess(int pid) async {
|
||||||
@@ -261,16 +178,14 @@ Future<bool> watchProcess(int pid) async {
|
|||||||
});
|
});
|
||||||
var errorPort = ReceivePort();
|
var errorPort = ReceivePort();
|
||||||
errorPort.listen((_) => completer.complete(false));
|
errorPort.listen((_) => completer.complete(false));
|
||||||
var isolate = await Isolate.spawn(
|
await Isolate.spawn(
|
||||||
_watchProcess,
|
_watchProcess,
|
||||||
pid,
|
pid,
|
||||||
onExit: exitPort.sendPort,
|
onExit: exitPort.sendPort,
|
||||||
onError: errorPort.sendPort,
|
onError: errorPort.sendPort,
|
||||||
errorsAreFatal: true
|
errorsAreFatal: true
|
||||||
);
|
);
|
||||||
var result = await completer.future;
|
return await completer.future;
|
||||||
isolate.kill(priority: Isolate.immediate);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> createRebootArgs(String username, String password, bool host, bool headless, String additionalArgs) {
|
List<String> createRebootArgs(String username, String password, bool host, bool headless, String additionalArgs) {
|
||||||
@@ -324,4 +239,53 @@ String _parseUsername(String username, bool host) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return username;
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ExtendedProcess extends Process {
|
||||||
|
final Process _delegate;
|
||||||
|
final Stream<List<int>>? _stdout;
|
||||||
|
final Stream<List<int>>? _stderr;
|
||||||
|
_ExtendedProcess(Process delegate, bool attached) :
|
||||||
|
_delegate = delegate,
|
||||||
|
_stdout = attached ? delegate.stdout.asBroadcastStream() : null,
|
||||||
|
_stderr = attached ? delegate.stderr.asBroadcastStream() : null;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<int> get exitCode => _delegate.exitCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool kill([ProcessSignal signal = ProcessSignal.sigterm]) => _delegate.kill(signal);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get pid => _delegate.pid;
|
||||||
|
|
||||||
|
@override
|
||||||
|
IOSink get stdin => _delegate.stdin;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<List<int>> get stdout {
|
||||||
|
final out = _stdout;
|
||||||
|
if(out == null) {
|
||||||
|
throw StateError("Output is not attached");
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<List<int>> get stderr {
|
||||||
|
final err = _stderr;
|
||||||
|
if(err == null) {
|
||||||
|
throw StateError("Output is not attached");
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ProcessExtension on Process {
|
||||||
|
Stream<String> get stdOutput => this.stdout.expand((event) => utf8.decode(event).split("\n"));
|
||||||
|
|
||||||
|
Stream<String> get stdError => this.stderr.expand((event) => utf8.decode(event).split("\n"));
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,8 @@ dependencies:
|
|||||||
ini: ^2.1.0
|
ini: ^2.1.0
|
||||||
shelf_proxy: ^1.0.2
|
shelf_proxy: ^1.0.2
|
||||||
sync: ^0.3.0
|
sync: ^0.3.0
|
||||||
|
uuid: ^3.0.6
|
||||||
|
shelf_web_socket: ^2.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^2.0.1
|
flutter_lints: ^2.0.1
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:reboot_common/common.dart';
|
|
||||||
import 'package:supabase/supabase.dart';
|
|
||||||
|
|
||||||
void main(List<String> args) async {
|
|
||||||
if(args.length != 5){
|
|
||||||
stderr.writeln("Wrong args length: $args");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var supabase = SupabaseClient(supabaseUrl, supabaseAnonKey);
|
|
||||||
var uuid = args[0];
|
|
||||||
var gamePid = int.parse(args[1]);
|
|
||||||
var launcherPid = int.parse(args[2]);
|
|
||||||
var eacPid = int.parse(args[3]);
|
|
||||||
var hosting = args[4].toLowerCase() == "true";
|
|
||||||
await watchProcess(gamePid);
|
|
||||||
Process.killPid(gamePid, ProcessSignal.sigabrt);
|
|
||||||
Process.killPid(launcherPid, ProcessSignal.sigabrt);
|
|
||||||
Process.killPid(eacPid, ProcessSignal.sigabrt);
|
|
||||||
if(hosting) {
|
|
||||||
await supabase.from("hosting")
|
|
||||||
.delete()
|
|
||||||
.match({'id': uuid});
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: reboot_watch
|
|
||||||
version: "1.0.0"
|
|
||||||
|
|
||||||
publish_to: 'none'
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: ">=2.19.0 <=3.3.4"
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
supabase: ^1.9.1
|
|
||||||
reboot_common:
|
|
||||||
path: ./../common
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
flutter_lints: ^2.0.1
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# ما هو مشروع Reboot؟
|
|
||||||
[Project Reboot](https://github.com/Milxnor/Project-Reboot-3.0) هو خادم ألعاب لـ Fortnite S3-S15
|
|
||||||
|
|
||||||
### من الذي بدأ المشروع؟
|
|
||||||
بدأ المشروع على Discord بواسطة Milxnor
|
|
||||||
[انضم إلى الديسكورد!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### من قام بتطوير الانشر؟
|
|
||||||
تم تطوير المشغل بالكامل بواسطة [Auties00](https://github.com/Auties00/reboot_launcher)
|
|
||||||
شكرًا لكل من ساهم في ترجمة المشغل إلى لغات أخرى!
|
|
||||||
|
|
||||||
### هل تتم صيانة المشروع بشكل نشط؟
|
|
||||||
لم تعد تتم صيانة المشروع بشكل نشط بعد الآن، ولكن لا يزال بإمكان المجتمع المساهمة في تطويره.
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# أين يمكنني الإبلاغ عن الأخطاء؟
|
|
||||||
|
|
||||||
## خادم اللعبة
|
|
||||||
|
|
||||||
### 1. جيثب
|
|
||||||
|
|
||||||
افتح مشكلة على [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. الديسكورد
|
|
||||||
اسأل في [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## الانشر
|
|
||||||
|
|
||||||
### 1. جيثب
|
|
||||||
|
|
||||||
افتح مشكلة على [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. الديسكورد
|
|
||||||
ضع علامة علىAuties في [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# كيف يمكنني جعل الخادم الخاص بي في مفتوح اللاعبين الآخرين؟
|
|
||||||
|
|
||||||
### 1. قم بتعيين عنوان IP ثابت
|
|
||||||
|
|
||||||
قم بتعيين عنوان IP ثابت على جهاز الكمبيوتر الذي يستضيف خادم اللعبة وانسخه لوقت لاحق:
|
|
||||||
|
|
||||||
- [ويندوز 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [ويندوز 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
|
|
||||||
### 2. قم بتسجيل الدخول إلى جهاز التوجيه الخاص بك
|
|
||||||
|
|
||||||
ستحتاج إلى الوصول إلى واجهة الويب الخاصة بجهاز التوجيه الخاص بك على 192.168.1.1.
|
|
||||||
قد تحتاج إلى اسم مستخدم وكلمة مرور لتسجيل الدخول: راجع دليل جهاز التوجيه الخاص بك للحصول على تعليمات دقيقة.
|
|
||||||
|
|
||||||
### 3. ابحث عن قسم إعادة توجيه المنفذ
|
|
||||||
|
|
||||||
بمجرد تسجيل الدخول، انتقل إلى قسم إعادة توجيه المنفذ في إعدادات جهاز التوجيه الخاص بك.
|
|
||||||
قد يختلف هذا الموقع من جهاز توجيه إلى آخر، ولكن يُطلق عليه عادةً اسم "Port Forwarding" أو "Port Mapping" أو "Virtual Server".
|
|
||||||
ارجع إلى دليل جهاز التوجيه الخاص بك للحصول على تعليمات دقيقة.
|
|
||||||
|
|
||||||
### 4. أضف قاعدة إعادة توجيه المنفذ
|
|
||||||
|
|
||||||
الآن، ستحتاج إلى إنشاء قاعدة جديدة لإعادة توجيه المنفذ. إليك ما ستحتاج عادةً إلى تحديده:
|
|
||||||
|
|
||||||
- **اسم الخدمة:** اختر اسمًا لقاعدة إعادة توجيه المنفذ (على سبيل المثال، "Fortnite Game Server").
|
|
||||||
- **رقم المنفذ:** أدخل 7777 لكل من المنافذ الخارجية والداخلية.
|
|
||||||
- **البروتوكول:** حدد بروتوكول UDP.
|
|
||||||
- **عنوان IP الداخلي:** أدخل عنوان IP الثابت الذي قمت بتعيينه مسبقًا.
|
|
||||||
- **تمكين:** تأكد من تمكين قاعدة إعادة توجيه المنفذ.
|
|
||||||
|
|
||||||
### 5. احفظ التغييرات وقم بتطبيقها
|
|
||||||
|
|
||||||
بعد تكوين قاعدة إعادة توجيه المنفذ، احفظ التغييرات وقم بتطبيقها.
|
|
||||||
قد تتضمن هذه الخطوة النقر فوق الزر "حفظ" أو "تطبيق" الموجود على واجهة الويب الخاصة بجهاز التوجيه الخاص بك.
|
|
||||||
|
|
||||||
### 6. حاول استضافة لعبة!
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Was ist Projekt Reboot?
|
|
||||||
[Projekt Reboot](https://github.com/Milxnor/Project-Reboot-3.0) is a game server for Fortnite S3-S15
|
|
||||||
|
|
||||||
### Wer hat das Projekt gestartet?
|
|
||||||
Das Projekt wurde auf Discord von Milxnor gestartet
|
|
||||||
[Trete dem Discord Server bei!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Wer entwickelt den Launcher?
|
|
||||||
Der Launcher is komplett von [Auties00](https://github.com/Auties00/reboot_launcher) entwickelt.
|
|
||||||
Danke an alle, die den Launcher in andere Sprachen übersetzt haben!
|
|
||||||
|
|
||||||
### Wird an dem Projekt noch aktiv gearbeitet?
|
|
||||||
An dem Projekt wird nicht mehr aktiv gearbeitet, aber die Community kann immer noch zu seiner Entwicklung beitragen.
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# Wo kann ich Bugs/Fehler einsenden?
|
|
||||||
|
|
||||||
## Game-Server
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Öffne ein Problem auf [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
|
|
||||||
Frag in [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Launcher
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Öffne ein Problem auf [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
|
|
||||||
Markiere @Auties in [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Wie kann ich andere Spieler auf meinen Server lassen?
|
|
||||||
|
|
||||||
### 1. Setze eine statische IP-Adresse (Static IP)
|
|
||||||
|
|
||||||
Setze eine statische IP-Adresse auf dem PC, auf dem der Server läuft und kopiere sie für später:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Logge dich in deinen Router ein
|
|
||||||
|
|
||||||
Du wirst das Web-Interface von deinem Router öffnen bei 192.168.1.1 müssen.
|
|
||||||
Vielleicht wirst du einen Benutzernamen und ein Passwort für den Log-In benötigen: Schau auf der Bedienung für deinen Router nach für prezise Vorgehensweisen.
|
|
||||||
|
|
||||||
### 3. Finde die Port-Forwarding Abteilung
|
|
||||||
|
|
||||||
Nachdem Sie sich angemeldet haben, gehen Sie zum Portweiterleitungsbereich der Einstellungen Ihres Routers.
|
|
||||||
Dieser Ort kann von Router zu Router variieren, ist jedoch normalerweise als "Portweiterleitung," "Portzuordnung" oder "Virtueller Server" gekennzeichnet.
|
|
||||||
Konsultieren Sie das Handbuch Ihres Routers für genaue Anweisungen.
|
|
||||||
|
|
||||||
### 4. Eine Port-Forwarding Regel hinzufügen
|
|
||||||
|
|
||||||
Nun müssen Sie eine neue Portweiterleitungsregel erstellen. Hier ist, was Sie normalerweise angeben müssen:
|
|
||||||
|
|
||||||
- **Dienstname**: Wählen Sie einen Namen für Ihre Portweiterleitungsregel (z.B. "Fortnite Game Server").
|
|
||||||
- **Portnummer**: Geben Sie sowohl für die externen als auch für die internen Ports die Nummer 7777 ein.
|
|
||||||
- **Protokoll**: Wählen Sie das UDP-Protokoll.
|
|
||||||
- **Interne IP-Adresse**: Geben Sie die statische IP-Adresse ein, die Sie zuvor festgelegt haben.
|
|
||||||
- **Aktivieren**: Stellen Sie sicher, dass die Portweiterleitungsregel aktiviert ist.
|
|
||||||
|
|
||||||
### 5. Änderungen speichern
|
|
||||||
|
|
||||||
Nachdem Sie die Portweiterleitungsregel konfiguriert haben, speichern Sie Ihre Änderungen und wenden Sie sie an.
|
|
||||||
Dieser Schritt kann das Klicken auf eine "Speichern" oder "Anwenden" Schaltfläche auf der Weboberfläche Ihres Routers erfordern.
|
|
||||||
|
|
||||||
### 6. Versuch, ein Spiel zu hosten!
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# What is Project Reboot?
|
|
||||||
[Project Reboot](https://github.com/Milxnor/Project-Reboot-3.0) is a game server for Fortnite S3-S15
|
|
||||||
|
|
||||||
### Who started the project?
|
|
||||||
The project was started on Discord by Milxnor
|
|
||||||
[Join the discord!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Who develops the launcher?
|
|
||||||
The launcher is entirely developed by [Auties00](https://github.com/Auties00/reboot_launcher)
|
|
||||||
Thanks to everyone who contributed to translate the launcher in other languages!
|
|
||||||
|
|
||||||
### Is the project being actively maintained?
|
|
||||||
The project isn't actively maintained anymore, but the community can still contribute to its development.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Where can I report bugs?
|
|
||||||
|
|
||||||
## Game server
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Open an issue on [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Ask in [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Launcher
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Open an issue on [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Tag @Auties in [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# How can I make my server accessible to other players?
|
|
||||||
|
|
||||||
### 1. Set a static IP
|
|
||||||
|
|
||||||
Set a static IP on the PC hosting the game server and copy it for later:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Log into Your Router
|
|
||||||
|
|
||||||
You'll need to access your router's web interface at 192.168.1.1.
|
|
||||||
You might need a username and a password to log in: refer to your router's manual for precise instructions.
|
|
||||||
|
|
||||||
### 3. Find the Port Forwarding Section
|
|
||||||
|
|
||||||
Once logged in, navigate to the port forwarding section of your router's settings.
|
|
||||||
This location may vary from router to router, but it's typically labelled as "Port Forwarding," "Port Mapping," or "Virtual Server."
|
|
||||||
Refer to your router's manual for precise instructions.
|
|
||||||
|
|
||||||
### 4. Add a Port Forwarding Rule
|
|
||||||
|
|
||||||
Now, you'll need to create a new port forwarding rule. Here's what you'll typically need to specify:
|
|
||||||
|
|
||||||
- **Service Name:** Choose a name for your port forwarding rule (e.g., "Fortnite Game Server").
|
|
||||||
- **Port Number:** Enter 7777 for both the external and internal ports.
|
|
||||||
- **Protocol:** Select the UDP protocol.
|
|
||||||
- **Internal IP Address:** Enter the static IP address you set earlier.
|
|
||||||
- **Enable:** Make sure the port forwarding rule is enabled.
|
|
||||||
|
|
||||||
### 5. Save and Apply the Changes
|
|
||||||
|
|
||||||
After configuring the port forwarding rule, save your changes and apply them.
|
|
||||||
This step may involve clicking a "Save" or "Apply" button on your router's web interface.
|
|
||||||
|
|
||||||
### 6. Try hosting a game!
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# ¿Qué es Project Reboot?
|
|
||||||
[Project Reboot](https://github.com/Milxnor/Project-Reboot-3.0) es un servidor de juego para Fortnite que abarca desde la temporada 3 hasta la temporada 15.
|
|
||||||
|
|
||||||
### ¿Quién inició el proyecto?
|
|
||||||
El proyecto fue iniciado en Discord por Milxnor.
|
|
||||||
[¡Únete al Discord!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### ¿Quién desarrolla el lanzador?
|
|
||||||
El lanzador está completamente desarrollado por [Auties00](https://github.com/Auties00/reboot_launcher). ¡Agradecemos a todos los que contribuyeron a traducir el lanzador a otros idiomas!
|
|
||||||
|
|
||||||
### ¿El proyecto se mantiene activamente?
|
|
||||||
El proyecto ya no se encuentra bajo mantenimiento activo, pero la comunidad aún puede contribuir a su desarrollo.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# ¿Dónde puedo reportar errores?
|
|
||||||
|
|
||||||
## Servidor de Juego
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Abre un issue en [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Pregunta en [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Launcher
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Abre un issue en [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Menciona a @Auties en [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# ¿Cómo puedo hacer que mi servidor sea accesible para otros jugadores?
|
|
||||||
|
|
||||||
### 1. Configurar una IP estática
|
|
||||||
|
|
||||||
Establece una IP estática en la PC que aloja el servidor de juego y cópiala para usarla más tarde:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
### 2. Iniciar sesión en tu Router
|
|
||||||
|
|
||||||
Necesitarás acceder a la interfaz web de tu router en 192.168.1.1.
|
|
||||||
Es posible que necesites un nombre de usuario y una contraseña para iniciar sesión: consulta el manual de tu router para instrucciones precisas.
|
|
||||||
|
|
||||||
### 3. Encuentra la Sección de Reenvío de Puertos
|
|
||||||
|
|
||||||
Una vez iniciada la sesión, ve a la sección de reenvío de puertos en la configuración de tu router.
|
|
||||||
Esta ubicación puede variar de un router a otro, pero generalmente está etiquetada como "Reenvío de Puertos", "Mapeo de Puertos" o "Servidor Virtual".
|
|
||||||
Consulta el manual de tu router para instrucciones precisas.
|
|
||||||
|
|
||||||
### 4. Agrega una Regla de Reenvío de Puertos
|
|
||||||
|
|
||||||
Ahora, deberás crear una nueva regla de reenvío de puertos. Esto es lo que normalmente necesitarás especificar:
|
|
||||||
|
|
||||||
- **Nombre del Servicio:** Elige un nombre para tu regla de reenvío de puertos (por ejemplo, "Servidor de Juego Fortnite").
|
|
||||||
- **Número de Puerto:** Ingresa 7777 tanto para los puertos externos como internos.
|
|
||||||
- **Protocolo:** Selecciona el protocolo UDP.
|
|
||||||
- **Dirección IP Interna:** Ingresa la dirección IP estática que configuraste anteriormente.
|
|
||||||
- **Habilitar:** Asegúrate de que la regla de reenvío de puertos esté habilitada.
|
|
||||||
|
|
||||||
### 5. Guarda y Aplica los Cambios
|
|
||||||
|
|
||||||
Después de configurar la regla de reenvío de puertos, guarda tus cambios y aplícalos.
|
|
||||||
Este paso puede implicar hacer clic en un botón "Guardar" o "Aplicar" en la interfaz web de tu router.
|
|
||||||
|
|
||||||
### 6. ¡Intenta hospedar un servidor de juego!
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Qu'est ce que c'est le "Project Reboot" ?
|
|
||||||
["Project Reboot"](https://github.com/Milxnor/Project-Reboot-3.0) est un serveur de jeu pour Fortnite S3-S15
|
|
||||||
|
|
||||||
### Qui a lancé le projet ?
|
|
||||||
Le projet à été lancé sur Discord par Milxnor
|
|
||||||
[Rejoignez le Discord !](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Qui développe le launcher de Reboot?
|
|
||||||
Le launcher est entièrement développé par [Auties00](https://github.com/Auties00/reboot_launcher)
|
|
||||||
Merci à tous ceux qui contribue à la traduction du launcher dans d'autres languages ! (🇫🇷 Dj_Mc01 & Dixip)
|
|
||||||
|
|
||||||
### Le projet est-il toujours mis à jour ?
|
|
||||||
Le projet n'est malheuresement plus activement maintenu, mais la communauté peut toujours contribuer au développement du [projet](https://github.com/Milxnor/Project-Reboot-3.0).
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Comment puis-je reporter des Bugs?
|
|
||||||
|
|
||||||
## Serveur de jeu
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Ouvrez une "issue" sur le [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Demandez dans [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Launcher
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Ouvrez une "issue" sur le [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Taggez @Auties dans [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Comment faire pour que mon serveur puisse être accessible par les autres joueurs ?
|
|
||||||
|
|
||||||
### 1. Définir une adresse IP locale statique (optionnel)
|
|
||||||
|
|
||||||
Définissez une adresse statique puis copiez là pour plus tard:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Se connecter sur l'interface de configuration de votre routeur
|
|
||||||
|
|
||||||
Pour y accéder, rendez-vous sur la bonne adresse, cela dépend de votre routeur (Orange & SFR: 192.168.1.1, Free: mafreebox.freebox.fr, Bouygues: 192.168.1.254)
|
|
||||||
|
|
||||||
**!!!Attention!!! certains opérateurs (comme SFR & Free) ne laissent plus accès à une IPv4 propre à leurs clients**, dans le cas de Free, vous devrez commander une ["IP FullStack"](https://subscribe.free.fr/login/) (c'est gratuit). Dans le cas d'SFR, vous devrez batailler avec le support client (ne perdez pas espoir, j'y suis parvenu en une semaine): +33 1023
|
|
||||||
|
|
||||||
Vous trouverez les informations d'authentifications dans le manuel de votre Box.
|
|
||||||
|
|
||||||
### 3. Trouver la section de configuration des ports
|
|
||||||
|
|
||||||
Une fois connectez sur le panel et votre IPv4 obtenue, cherchez la page des options pour ouvrir vos ports
|
|
||||||
Ceci varie beacoup en fonction du routeur, mais c'est souvent appelée "NAT/PAT", "Gestion des ports" ou encore "Port Forwarding".
|
|
||||||
Sinon, réferez vous à des guides sur Google ou autre...
|
|
||||||
|
|
||||||
### 4. Ajouter la règle
|
|
||||||
|
|
||||||
Maintenant, vous devez créer la règle pour autoriser les joueurs à se connecter, rentrez les informations suivantes:
|
|
||||||
|
|
||||||
- **Nom:** Choisissez un nom pour votre règle, "Fortnite serveur" ? Peu importe...
|
|
||||||
- **Ports:** Entrez 7777 pour le port interne et externe (s'il vous demande une plage, spécifiez 7777 partout).
|
|
||||||
- **Protocole:** Sélectionnez UDP (ou les deux si possible).
|
|
||||||
- **IP de destination:** Entrez l'IP locale de votre serveur, celle précédemment spécifiée, ou sélectionnez votre appareil par son nom dans la liste (si disponible).
|
|
||||||
- **Activation:** Soyez-sûre que la règle est activée, bien évidemment.
|
|
||||||
|
|
||||||
### 5. Sauvegardez et appliquez les changements.
|
|
||||||
|
|
||||||
Après avoir spécifié votre règle, n'oubliez pas de sauvegarder.
|
|
||||||
|
|
||||||
### 6. Essayez de lancer une partie !
|
|
||||||
|
|
||||||
Si tout s'est correctement déroulé, les joueurs devraient être en possibilité de rejoindre votre serveur.
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Czym jest Project Reboot?
|
|
||||||
[Project Reboot](https://github.com/Milxnor/Project-Reboot-3.0) to serwer gry dla Fortnite S3-S15
|
|
||||||
|
|
||||||
### Kto rozpoczął projekt?
|
|
||||||
Projekt został zapoczątkowany na Discordzie przez Milxnora
|
|
||||||
[Dołącz do Discorda!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Kto rozwija launcher?
|
|
||||||
Program uruchamiający został w całości opracowany przez [Auties00](https://github.com/Auties00/reboot_launcher).
|
|
||||||
Dziękujemy wszystkim, którzy przyczynili się do przetłumaczenia launchera na inne języki! (Przetłumaczono na Polski przez: TKD_Kedis)
|
|
||||||
|
|
||||||
### Czy projekt jest aktywnie rozwijany?
|
|
||||||
Projekt nie jest już aktywnie rozwijany, ale społeczność nadal może przyczyniać się do jego rozwoju.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Gdzie mogę zgłaszać błędy?
|
|
||||||
|
|
||||||
## Serwer gry
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Otwórz zgłoszenie na [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Zapytaj w [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Program uruchamiający
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Otwórz zgłoszenie na [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Oznacz @Auties w [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Jak mogę udostępnić mój serwer innym graczom?
|
|
||||||
|
|
||||||
### 1. Ustaw statyczny adres IP
|
|
||||||
|
|
||||||
Ustaw statyczny adres IP na komputerze hostującym serwer gry i skopiuj go na później:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Zaloguj się do routera
|
|
||||||
|
|
||||||
Musisz uzyskać dostęp do interfejsu internetowego routera pod adresem 192.168.1.1.
|
|
||||||
Do zalogowania może być potrzebna nazwa użytkownika i hasło: dokładne instrukcje można znaleźć w instrukcji obsługi routera.
|
|
||||||
|
|
||||||
### 3. Znajdź sekcję Przekierowanie portów
|
|
||||||
|
|
||||||
Po zalogowaniu przejdź do sekcji przekierowania portów w ustawieniach routera.
|
|
||||||
Lokalizacja ta może się różnić w zależności od routera, ale zazwyczaj jest oznaczona jako "Przekierowanie portów", "Mapowanie portów" lub "Serwer wirtualny".
|
|
||||||
Dokładne instrukcje można znaleźć w instrukcji obsługi routera.
|
|
||||||
|
|
||||||
### 4. Dodaj regułę przekierowania portów
|
|
||||||
|
|
||||||
Teraz musisz utworzyć nową regułę przekierowania portów. Oto, co zazwyczaj należy określić:
|
|
||||||
|
|
||||||
- **Nazwa usługi:** Wybierz nazwę dla swojej reguły przekierowania portów (np. "Fortnite Game Server").
|
|
||||||
- **Numer portu:** Wprowadź 7777 dla portów zewnętrznych i wewnętrznych.
|
|
||||||
- **Protokół:** Wybierz protokół UDP.
|
|
||||||
- **Wewnętrzny adres IP:** Wprowadź statyczny adres IP, który ustawiłeś wcześniej.
|
|
||||||
- **Włącz:** Upewnij się, że reguła przekierowania portów jest włączona.
|
|
||||||
|
|
||||||
### 5. Zapisz i zastosuj zmiany
|
|
||||||
|
|
||||||
Po skonfigurowaniu reguły przekierowania portów, zapisz zmiany i zastosuj je.
|
|
||||||
Ten krok może wymagać kliknięcia przycisku "Zapisz" lub "Zastosuj" na stronie internetowej routera.
|
|
||||||
|
|
||||||
### 6. Spróbuj zhostować grę!
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# O que é o Projeto Reboot?
|
|
||||||
[Projeto Reboot](https://github.com/Milxnor/Project-Reboot-3.0) é um servidor de jogo para Fortnite da temporada 3 à temporada 15.
|
|
||||||
|
|
||||||
### Quem iniciou o projeto?
|
|
||||||
O projeto foi iniciado no Discord por Milxnor.
|
|
||||||
[Entre no Discord!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Quem desenvolve o launcher?
|
|
||||||
O launcher é completamente desenvolvido por [Auties00](https://github.com/Auties00/reboot_launcher). Agradecemos a todos que contribuíram para traduzir o launcher para outros idiomas!
|
|
||||||
|
|
||||||
### O projeto está sendo ativamente mantido?
|
|
||||||
O projeto não está mais sendo ativamente mantido, mas a comunidade ainda pode contribuir para o seu desenvolvimento.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Onde posso reportar bugs?
|
|
||||||
|
|
||||||
## Servidor de Jogo
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Abra um issue no [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Pergunte em [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Launcher
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Abra um issue no [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Marque @Auties em [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Como posso tornar meu servidor acessível para outros jogadores?
|
|
||||||
|
|
||||||
### 1. Configure um IP estático
|
|
||||||
|
|
||||||
Configure um IP estático no PC que hospeda o servidor de jogo e copie-o para uso posterior:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
### 2. Faça login no seu Roteador
|
|
||||||
|
|
||||||
Você precisará acessar a interface web do seu roteador em 192.168.1.1 ou 192.168.0.1.
|
|
||||||
Lembre-se que a IP de acesso ao seu roteador pode mudar conforme o seu provedor de internet.
|
|
||||||
Poderá ser necessário um nome de usuário e senha para fazer o login: consulte o manual do seu roteador para instruções precisas.
|
|
||||||
|
|
||||||
### 3. Encontre a Seção de Redirecionamento de Porta
|
|
||||||
|
|
||||||
Após fazer login, vá para a seção de redirecionamento de porta nas configurações do seu roteador.
|
|
||||||
A localização pode variar de um roteador para outro, mas geralmente é rotulada como "Redirecionamento de Porta," "Mapeamento de Porta" ou "Servidor Virtual."
|
|
||||||
Consulte o manual do seu roteador para instruções precisas.
|
|
||||||
|
|
||||||
### 4. Adicione uma Regra de Redirecionamento de Porta
|
|
||||||
|
|
||||||
Agora, você precisará criar uma nova regra de redirecionamento de porta. Eis o que normalmente você precisará especificar:
|
|
||||||
|
|
||||||
- **Nome do Serviço:** Escolha um nome para sua regra de redirecionamento de porta (por exemplo, "Servidor de Jogo Fortnite").
|
|
||||||
- **Número da Porta:** Insira 7777 para ambas as portas externa e interna.
|
|
||||||
- **Protocolo:** Selecione o protocolo UDP.
|
|
||||||
- **Endereço IP Interno:** Insira o endereço IP estático que você configurou anteriormente.
|
|
||||||
- **Ativar:** Certifique-se de que a regra de redirecionamento de porta esteja ativada.
|
|
||||||
|
|
||||||
### 5. Salve e Aplique as Alterações
|
|
||||||
|
|
||||||
Após configurar a regra de redirecionamento de porta, salve suas alterações e aplique-as.
|
|
||||||
Isso pode envolver clicar em um botão "Salvar" ou "Aplicar" na interface web do seu roteador.
|
|
||||||
|
|
||||||
### 6. Tente hospedar um jogo!
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Ce este Proiectul Reboot?
|
|
||||||
[Proiectul Reboot](https://github.com/Milxnor/Project-Reboot-3.0) este un server de joc pentru Fortnite S3-S15
|
|
||||||
|
|
||||||
### Cine a inițiat proiectul?
|
|
||||||
Proiectul a fost inițiat pe Discord de Milxnor
|
|
||||||
[Intrați pe discord!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Cine dezvoltă lansatorul?
|
|
||||||
Lansatorul este dezvoltat în întregime de [Auties00](https://github.com/Auties00/reboot_launcher)
|
|
||||||
Mulțumim tuturor celor care au contribuit la traducerea lansatorului în alte limbi!
|
|
||||||
|
|
||||||
### Proiectul este întreținut în mod activ?
|
|
||||||
Proiectul nu mai este întreținut în mod activ, dar comunitatea poate contribui în continuare la dezvoltarea sa.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Unde pot raporta bug-uri?
|
|
||||||
|
|
||||||
## Server de joc
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Deschideți o problemă pe [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Întrebați pe canalul [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Lansator
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Deschideți o problemă pe [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Etichetați @Auties în [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
# Cum îmi pot face serverul accesibil altor jucători?
|
|
||||||
|
|
||||||
### 1. Setați un IP static
|
|
||||||
|
|
||||||
Setați un IP static pe PC-ul care găzduiește serverul de joc și copiați-l pentru mai târziu:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Conectați-vă la router
|
|
||||||
|
|
||||||
Va trebui să accesați interfața web a routerului la 192.168.1.1.
|
|
||||||
Este posibil să aveți nevoie de un nume de utilizator și de o parolă pentru a vă conecta: consultați manualul routerului pentru instrucțiuni precise.
|
|
||||||
|
|
||||||
### 3. Găsiți secțiunea Port Forwarding
|
|
||||||
|
|
||||||
Odată ce v-ați conectat, navigați la secțiunea de Port Forwarding din setările routerului.
|
|
||||||
Această secțiune poate varia de la un router la altul, dar de obicei este etichetată ca "Port Forwarding", "Port Mapping" sau "Virtual Server".
|
|
||||||
Consultați manualul routerului dumneavoastră pentru instrucțiuni precise.
|
|
||||||
|
|
||||||
### 4. Adăugați o regulă pentru Port Forwarding
|
|
||||||
|
|
||||||
Acum va trebui să creați o nouă regulă pentru "Port Forwarding". Iată ce va trebui să specificați în mod obișnuit:
|
|
||||||
|
|
||||||
- **Denumirea serviciului:** Alegeți un nume pentru Port Forwarding (de exemplu, "Fortnite Game Server").
|
|
||||||
- **Numărul portului:** Introduceți 7777 atât pentru portul extern, cât și pentru cel intern.
|
|
||||||
- **Protocolul:** Selectați protocolul UDP.
|
|
||||||
- **Adresa IP internă:** Introduceți adresa IP statică pe care ați introdus-o mai devreme.
|
|
||||||
- **Activați:** Asigurați-vă că regula de redirecționare a portului este activată.
|
|
||||||
|
|
||||||
### 5. Salvați și Aplicați modificările
|
|
||||||
|
|
||||||
După configurarea Port Forwarding-ului, salvați modificările și aplicați-le.
|
|
||||||
Acest pas poate implica apăsarea butonului "Save" (Salvare) sau "Apply" (Aplicare) pe interfața web a routerului.
|
|
||||||
|
|
||||||
### 6. Încercați să găzduiți un meci!
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Что такое проект Reboot?
|
|
||||||
[Project Reboot](https://github.com/Milxnor/Project-Reboot-3.0) - это игровой сервер для Fortnite с сезона 3 по 15.
|
|
||||||
|
|
||||||
### Кто начал этот проект?
|
|
||||||
Проект был начат на сервере Discord пользователем с никнеймом Milxnor.
|
|
||||||
[Присоединяйтесь к серверу Discord!](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
### Кто разрабатывает лаунчер?
|
|
||||||
Лаунчер полностью разрабатывается [Auties00](https://github.com/Auties00/reboot_launcher).
|
|
||||||
Спасибо всем, кто внес свой вклад в перевод лаунчера на другие языки!
|
|
||||||
|
|
||||||
### Проект активно поддерживается?
|
|
||||||
Проект больше не активно поддерживается, однако сообщество все еще может вносить свой вклад в его развитие.
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# Где я могу сообщить о багах?
|
|
||||||
|
|
||||||
## Сервер
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Создайте запрос на [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Задайте вопрос в [#help](https://discord.gg/reboot)
|
|
||||||
|
|
||||||
## Лаунчер
|
|
||||||
|
|
||||||
### 1. Github
|
|
||||||
|
|
||||||
Создайте запрос на [Github](https://github.com/Milxnor/Project-Reboot-3.0/issues)
|
|
||||||
|
|
||||||
### 2. Discord
|
|
||||||
Отметьте пользователя @Auties в [#launcher-issues](https://discord.gg/reboot)
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Как сделать свой сервер доступным для других игроков?
|
|
||||||
|
|
||||||
### 1. Задайте статический IP
|
|
||||||
|
|
||||||
Установите статический IP на ПК, на котором размещен игровой сервер, и скопируйте его для последующего использования:
|
|
||||||
|
|
||||||
- [Windows 11](https://pureinfotech.com/set-static-ip-address-windows-11/)
|
|
||||||
- [Windows 10](https://pureinfotech.com/set-static-ip-address-windows-10/)
|
|
||||||
|
|
||||||
### 2. Войдите в свой роутер
|
|
||||||
|
|
||||||
Для доступа к веб-интерфейсу вашего роутера перейдите по адресу 192.168.1.1.
|
|
||||||
Может потребоваться имя пользователя и пароль для входа: обратитесь к руководству вашего роутера за точными инструкциями.
|
|
||||||
|
|
||||||
### 3. Найдите раздел "Перенаправление портов"
|
|
||||||
|
|
||||||
После входа перейдите в раздел настроек роутера, связанный с перенаправлением портов. Местоположение этого раздела может различаться от роутера к роутеру, но обычно он обозначается как "Перенаправление портов", "Назначение портов" или "Виртуальный сервер".
|
|
||||||
Смотрите в руководстве к роутеру для точных инструкций.
|
|
||||||
|
|
||||||
### 4. Добавьте правило перенаправления портов
|
|
||||||
|
|
||||||
Теперь вам нужно создать новое правило перенаправления портов. Вот что обычно нужно указать:
|
|
||||||
|
|
||||||
- **Имя сервиса:** Выберите имя для вашего правила перенаправления портов (например, "Игровой сервер Fortnite").
|
|
||||||
- **Номер порта:** Введите 7777 как для внешнего, так и для внутреннего порта.
|
|
||||||
- **Протокол:** Выберите протокол UDP.
|
|
||||||
- **Внутренний IP-адрес:** Введите статический IP-адрес, который вы установили ранее.
|
|
||||||
- **Включить:** Убедитесь, что правило перенаправления портов включено.
|
|
||||||
|
|
||||||
### 5. Сохраните и примените изменения
|
|
||||||
|
|
||||||
После настройки правила перенаправления портов сохраните ваши изменения и примените их.
|
|
||||||
Этот шаг может включать в себя нажатие кнопки "Сохранить" или "Применить" на веб-интерфейсе вашего роутера.
|
|
||||||
|
|
||||||
### 6. Попробуйте запустить сервер!
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Do not remove/change, this redirects epicgames xmpp to lawinserver xmpp
|
|
||||||
[OnlineSubsystemMcp.Xmpp]
|
|
||||||
bUseSSL=false
|
|
||||||
ServerAddr="ws://127.0.0.1"
|
|
||||||
ServerPort=80
|
|
||||||
|
|
||||||
# Do not remove/change, this redirects epicgames xmpp to lawinserver xmpp
|
|
||||||
[OnlineSubsystemMcp.Xmpp Prod]
|
|
||||||
bUseSSL=false
|
|
||||||
ServerAddr="ws://127.0.0.1"
|
|
||||||
ServerPort=80
|
|
||||||
@@ -1,526 +0,0 @@
|
|||||||
[
|
|
||||||
"Defender:did_defenderassault_basic_c_t01",
|
|
||||||
"Defender:did_defenderassault_basic_r_t01",
|
|
||||||
"Defender:did_defenderassault_basic_sr_t01",
|
|
||||||
"Defender:did_defenderassault_basic_uc_t01",
|
|
||||||
"Defender:did_defenderassault_basic_vr_t01",
|
|
||||||
"Defender:did_defenderassault_founders_vr_t01",
|
|
||||||
"Defender:did_defendermelee_basic_c_t01",
|
|
||||||
"Defender:did_defendermelee_basic_r_t01",
|
|
||||||
"Defender:did_defendermelee_basic_sr_t01",
|
|
||||||
"Defender:did_defendermelee_basic_uc_t01",
|
|
||||||
"Defender:did_defendermelee_basic_vr_t01",
|
|
||||||
"Defender:did_defenderpistol_basic_c_t01",
|
|
||||||
"Defender:did_defenderpistol_basic_r_t01",
|
|
||||||
"Defender:did_defenderpistol_basic_sr_t01",
|
|
||||||
"Defender:did_defenderpistol_basic_uc_t01",
|
|
||||||
"Defender:did_defenderpistol_basic_vr_t01",
|
|
||||||
"Defender:did_defenderpistol_founders_vr_t01",
|
|
||||||
"Defender:did_defendershotgun_basic_c_t01",
|
|
||||||
"Defender:did_defendershotgun_basic_r_t01",
|
|
||||||
"Defender:did_defendershotgun_basic_sr_t01",
|
|
||||||
"Defender:did_defendershotgun_basic_uc_t01",
|
|
||||||
"Defender:did_defendershotgun_basic_vr_t01",
|
|
||||||
"Defender:did_defendersniper_basic_c_t01",
|
|
||||||
"Defender:did_defendersniper_basic_r_t01",
|
|
||||||
"Defender:did_defendersniper_basic_sr_t01",
|
|
||||||
"Defender:did_defendersniper_basic_uc_t01",
|
|
||||||
"Defender:did_defendersniper_basic_vr_t01",
|
|
||||||
"Hero:hid_commando_007_r_t01",
|
|
||||||
"Hero:hid_commando_007_sr_t01",
|
|
||||||
"Hero:hid_commando_007_uc_t01",
|
|
||||||
"Hero:hid_commando_007_vr_t01",
|
|
||||||
"Hero:hid_commando_008_foundersf_sr_t01",
|
|
||||||
"Hero:hid_commando_008_foundersm_sr_t01",
|
|
||||||
"Hero:hid_commando_008_r_t01",
|
|
||||||
"Hero:hid_commando_008_sr_t01",
|
|
||||||
"Hero:hid_commando_008_vr_t01",
|
|
||||||
"Hero:hid_commando_009_r_t01",
|
|
||||||
"Hero:hid_commando_009_sr_t01",
|
|
||||||
"Hero:hid_commando_009_vr_t01",
|
|
||||||
"Hero:hid_commando_010_sr_t01",
|
|
||||||
"Hero:hid_commando_010_vr_t01",
|
|
||||||
"Hero:hid_commando_gcgrenade_r_t01",
|
|
||||||
"Hero:hid_commando_gcgrenade_sr_t01",
|
|
||||||
"Hero:hid_commando_gcgrenade_vr_t01",
|
|
||||||
"Hero:hid_commando_grenadegun_r_t01",
|
|
||||||
"Hero:hid_commando_grenadegun_sr_t01",
|
|
||||||
"Hero:hid_commando_grenadegun_uc_t01",
|
|
||||||
"Hero:hid_commando_grenadegun_vr_t01",
|
|
||||||
"Hero:hid_commando_grenademaster_sr_t01",
|
|
||||||
"Hero:hid_commando_gunheadshot_sr_t01",
|
|
||||||
"Hero:hid_commando_gunheadshot_vr_t01",
|
|
||||||
"Hero:hid_commando_gunheadshothw_sr_t01",
|
|
||||||
"Hero:hid_commando_guntough_r_t01",
|
|
||||||
"Hero:hid_commando_guntough_sr_t01",
|
|
||||||
"Hero:hid_commando_guntough_uc_t01",
|
|
||||||
"Hero:hid_commando_guntough_vr_t01",
|
|
||||||
"Hero:hid_commando_shockdamage_r_t01",
|
|
||||||
"Hero:hid_commando_shockdamage_sr_t01",
|
|
||||||
"Hero:hid_commando_shockdamage_vr_t01",
|
|
||||||
"Hero:hid_commando_sony_r_t01",
|
|
||||||
"Hero:hid_constructor_007_r_t01",
|
|
||||||
"Hero:hid_constructor_007_sr_t01",
|
|
||||||
"Hero:hid_constructor_007_uc_t01",
|
|
||||||
"Hero:hid_constructor_007_vr_t01",
|
|
||||||
"Hero:hid_constructor_008_foundersf_sr_t01",
|
|
||||||
"Hero:hid_constructor_008_foundersm_sr_t01",
|
|
||||||
"Hero:hid_constructor_008_r_t01",
|
|
||||||
"Hero:hid_constructor_008_sr_t01",
|
|
||||||
"Hero:hid_constructor_008_vr_t01",
|
|
||||||
"Hero:hid_constructor_009_r_t01",
|
|
||||||
"Hero:hid_constructor_009_sr_t01",
|
|
||||||
"Hero:hid_constructor_009_vr_t01",
|
|
||||||
"Hero:hid_constructor_010_sr_t01",
|
|
||||||
"Hero:hid_constructor_010_vr_t01",
|
|
||||||
"Hero:hid_constructor_basebig_sr_t01",
|
|
||||||
"Hero:hid_constructor_basehyper_r_t01",
|
|
||||||
"Hero:hid_constructor_basehyper_sr_t01",
|
|
||||||
"Hero:hid_constructor_basehyper_vr_t01",
|
|
||||||
"Hero:hid_constructor_basehyperhw_sr_t01",
|
|
||||||
"Hero:hid_constructor_hammerplasma_sr_t01",
|
|
||||||
"Hero:hid_constructor_hammerplasma_vr_t01",
|
|
||||||
"Hero:hid_constructor_hammertank_r_t01",
|
|
||||||
"Hero:hid_constructor_hammertank_sr_t01",
|
|
||||||
"Hero:hid_constructor_hammertank_uc_t01",
|
|
||||||
"Hero:hid_constructor_hammertank_vr_t01",
|
|
||||||
"Hero:hid_constructor_plasmadamage_r_t01",
|
|
||||||
"Hero:hid_constructor_plasmadamage_sr_t01",
|
|
||||||
"Hero:hid_constructor_plasmadamage_vr_t01",
|
|
||||||
"Hero:hid_constructor_rushbase_r_t01",
|
|
||||||
"Hero:hid_constructor_rushbase_sr_t01",
|
|
||||||
"Hero:hid_constructor_rushbase_uc_t01",
|
|
||||||
"Hero:hid_constructor_rushbase_vr_t01",
|
|
||||||
"Hero:hid_constructor_sony_r_t01",
|
|
||||||
"Hero:hid_ninja_007_r_t01",
|
|
||||||
"Hero:hid_ninja_007_sr_t01",
|
|
||||||
"Hero:hid_ninja_007_uc_t01",
|
|
||||||
"Hero:hid_ninja_007_vr_t01",
|
|
||||||
"Hero:hid_ninja_008_r_t01",
|
|
||||||
"Hero:hid_ninja_008_sr_t01",
|
|
||||||
"Hero:hid_ninja_008_vr_t01",
|
|
||||||
"Hero:hid_ninja_009_r_t01",
|
|
||||||
"Hero:hid_ninja_009_sr_t01",
|
|
||||||
"Hero:hid_ninja_009_vr_t01",
|
|
||||||
"Hero:hid_ninja_010_sr_t01",
|
|
||||||
"Hero:hid_ninja_010_vr_t01",
|
|
||||||
"Hero:hid_ninja_slashbreath_r_t01",
|
|
||||||
"Hero:hid_ninja_slashbreath_sr_t01",
|
|
||||||
"Hero:hid_ninja_slashbreath_vr_t01",
|
|
||||||
"Hero:hid_ninja_slashtail_r_t01",
|
|
||||||
"Hero:hid_ninja_slashtail_sr_t01",
|
|
||||||
"Hero:hid_ninja_slashtail_uc_t01",
|
|
||||||
"Hero:hid_ninja_slashtail_vr_t01",
|
|
||||||
"Hero:hid_ninja_smokedimmak_r_t01",
|
|
||||||
"Hero:hid_ninja_smokedimmak_sr_t01",
|
|
||||||
"Hero:hid_ninja_smokedimmak_vr_t01",
|
|
||||||
"Hero:hid_ninja_sony_r_t01",
|
|
||||||
"Hero:hid_ninja_starsassassin_foundersf_sr_t01",
|
|
||||||
"Hero:hid_ninja_starsassassin_foundersm_sr_t01",
|
|
||||||
"Hero:hid_ninja_starsassassin_r_t01",
|
|
||||||
"Hero:hid_ninja_starsassassin_sr_t01",
|
|
||||||
"Hero:hid_ninja_starsassassin_uc_t01",
|
|
||||||
"Hero:hid_ninja_starsassassin_vr_t01",
|
|
||||||
"Hero:hid_ninja_starsrain_sr_t01",
|
|
||||||
"Hero:hid_ninja_starsrain_vr_t01",
|
|
||||||
"Hero:hid_ninja_starsrainhw_sr_t01",
|
|
||||||
"Hero:hid_ninja_swordmaster_sr_t01",
|
|
||||||
"Hero:hid_outlander_007_r_t01",
|
|
||||||
"Hero:hid_outlander_007_sr_t01",
|
|
||||||
"Hero:hid_outlander_007_uc_t01",
|
|
||||||
"Hero:hid_outlander_007_vr_t01",
|
|
||||||
"Hero:hid_outlander_008_foundersf_sr_t01",
|
|
||||||
"Hero:hid_outlander_008_foundersm_sr_t01",
|
|
||||||
"Hero:hid_outlander_008_r_t01",
|
|
||||||
"Hero:hid_outlander_008_sr_t01",
|
|
||||||
"Hero:hid_outlander_008_vr_t01",
|
|
||||||
"Hero:hid_outlander_009_r_t01",
|
|
||||||
"Hero:hid_outlander_009_sr_t01",
|
|
||||||
"Hero:hid_outlander_009_vr_t01",
|
|
||||||
"Hero:hid_outlander_010_sr_t01",
|
|
||||||
"Hero:hid_outlander_010_vr_t01",
|
|
||||||
"Hero:hid_outlander_punchdamage_sr_t01",
|
|
||||||
"Hero:hid_outlander_punchdamage_vr_t01",
|
|
||||||
"Hero:hid_outlander_punchphase_r_t01",
|
|
||||||
"Hero:hid_outlander_punchphase_sr_t01",
|
|
||||||
"Hero:hid_outlander_punchphase_uc_t01",
|
|
||||||
"Hero:hid_outlander_punchphase_vr_t01",
|
|
||||||
"Hero:hid_outlander_sony_r_t01",
|
|
||||||
"Hero:hid_outlander_spherefragment_r_t01",
|
|
||||||
"Hero:hid_outlander_spherefragment_sr_t01",
|
|
||||||
"Hero:hid_outlander_spherefragment_vr_t01",
|
|
||||||
"Hero:hid_outlander_zonefragment_sr_t01",
|
|
||||||
"Hero:hid_outlander_zoneharvest_r_t01",
|
|
||||||
"Hero:hid_outlander_zoneharvest_sr_t01",
|
|
||||||
"Hero:hid_outlander_zoneharvest_uc_t01",
|
|
||||||
"Hero:hid_outlander_zoneharvest_vr_t01",
|
|
||||||
"Hero:hid_outlander_zonepistol_r_t01",
|
|
||||||
"Hero:hid_outlander_zonepistol_sr_t01",
|
|
||||||
"Hero:hid_outlander_zonepistol_vr_t01",
|
|
||||||
"Hero:hid_outlander_zonepistolhw_sr_t01",
|
|
||||||
"Schematic:sid_assault_auto_c_ore_t01",
|
|
||||||
"Schematic:sid_assault_auto_founders_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_auto_halloween_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_auto_r_ore_t01",
|
|
||||||
"Schematic:sid_assault_auto_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_auto_uc_ore_t01",
|
|
||||||
"Schematic:sid_assault_auto_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_burst_c_ore_t01",
|
|
||||||
"Schematic:sid_assault_burst_r_ore_t01",
|
|
||||||
"Schematic:sid_assault_burst_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_burst_uc_ore_t01",
|
|
||||||
"Schematic:sid_assault_burst_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_doubleshot_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_doubleshot_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_hydra_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_lmg_drum_founders_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_lmg_drum_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_lmg_r_ore_t01",
|
|
||||||
"Schematic:sid_assault_lmg_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_lmg_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_raygun_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_raygun_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_semiauto_c_ore_t01",
|
|
||||||
"Schematic:sid_assault_semiauto_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_semiauto_r_ore_t01",
|
|
||||||
"Schematic:sid_assault_semiauto_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_semiauto_uc_ore_t01",
|
|
||||||
"Schematic:sid_assault_semiauto_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_singleshot_r_ore_t01",
|
|
||||||
"Schematic:sid_assault_singleshot_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_singleshot_vr_ore_t01",
|
|
||||||
"Schematic:sid_assault_surgical_drum_founders_r_ore_t01",
|
|
||||||
"Schematic:sid_assault_surgical_sr_ore_t01",
|
|
||||||
"Schematic:sid_assault_surgical_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_club_light_sr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_club_light_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_heavy_c_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_heavy_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_heavy_r_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_heavy_sr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_heavy_uc_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_heavy_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_rocket_sr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_hammer_rocket_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_heavy_paddle_c_ore_t01",
|
|
||||||
"Schematic:sid_blunt_heavy_paddle_r_ore_t01",
|
|
||||||
"Schematic:sid_blunt_heavy_paddle_uc_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_bat_r_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_bat_uc_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_c_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_r_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_rocketbat_sr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_rocketbat_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_sr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_uc_ore_t01",
|
|
||||||
"Schematic:sid_blunt_light_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_medium_c_ore_t01",
|
|
||||||
"Schematic:sid_blunt_medium_r_ore_t01",
|
|
||||||
"Schematic:sid_blunt_medium_sr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_medium_uc_ore_t01",
|
|
||||||
"Schematic:sid_blunt_medium_vr_ore_t01",
|
|
||||||
"Schematic:sid_blunt_tool_light_r_ore_t01",
|
|
||||||
"Schematic:sid_blunt_tool_light_uc_ore_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_aoe_r_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_aoe_sr_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_aoe_vr_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_single_c_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_single_r_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_single_sr_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_single_uc_t01",
|
|
||||||
"Schematic:sid_ceiling_electric_single_vr_t01",
|
|
||||||
"Schematic:sid_ceiling_gas_r_t01",
|
|
||||||
"Schematic:sid_ceiling_gas_sr_t01",
|
|
||||||
"Schematic:sid_ceiling_gas_uc_t01",
|
|
||||||
"Schematic:sid_ceiling_gas_vr_t01",
|
|
||||||
"Schematic:sid_edged_axe_heavy_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_heavy_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_heavy_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_heavy_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_heavy_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_light_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_light_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_light_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_light_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_light_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_laser_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_laser_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_axe_medium_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_laser_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_laser_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_scythe_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_heavy_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_heavy_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_heavy_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_heavy_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_heavy_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_heavy_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_hydraulic_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_hydraulic_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_light_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_light_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_light_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_light_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_light_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_light_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_c_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_laser_founders_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_laser_founders_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_laser_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_laser_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_laser_vr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_r_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_sr_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_uc_ore_t01",
|
|
||||||
"Schematic:sid_edged_sword_medium_vr_ore_t01",
|
|
||||||
"Schematic:sid_floor_health_r_t01",
|
|
||||||
"Schematic:sid_floor_health_sr_t01",
|
|
||||||
"Schematic:sid_floor_health_uc_t01",
|
|
||||||
"Schematic:sid_floor_health_vr_t01",
|
|
||||||
"Schematic:sid_floor_launcher_r_t01",
|
|
||||||
"Schematic:sid_floor_launcher_sr_t01",
|
|
||||||
"Schematic:sid_floor_launcher_uc_t01",
|
|
||||||
"Schematic:sid_floor_launcher_vr_t01",
|
|
||||||
"Schematic:sid_floor_spikes_r_t01",
|
|
||||||
"Schematic:sid_floor_spikes_sr_t01",
|
|
||||||
"Schematic:sid_floor_spikes_uc_t01",
|
|
||||||
"Schematic:sid_floor_spikes_vr_t01",
|
|
||||||
"Schematic:sid_floor_spikes_wood_c_t01",
|
|
||||||
"Schematic:sid_floor_spikes_wood_r_t01",
|
|
||||||
"Schematic:sid_floor_spikes_wood_sr_t01",
|
|
||||||
"Schematic:sid_floor_spikes_wood_uc_t01",
|
|
||||||
"Schematic:sid_floor_spikes_wood_vr_t01",
|
|
||||||
"Schematic:sid_floor_ward_r_t01",
|
|
||||||
"Schematic:sid_floor_ward_sr_t01",
|
|
||||||
"Schematic:sid_floor_ward_uc_t01",
|
|
||||||
"Schematic:sid_floor_ward_vr_t01",
|
|
||||||
"Schematic:sid_launcher_grenade_r_ore_t01",
|
|
||||||
"Schematic:sid_launcher_grenade_sr_ore_t01",
|
|
||||||
"Schematic:sid_launcher_grenade_vr_ore_t01",
|
|
||||||
"Schematic:sid_launcher_hydraulic_sr_ore_t01",
|
|
||||||
"Schematic:sid_launcher_hydraulic_vr_ore_t01",
|
|
||||||
"Schematic:sid_launcher_pumpkin_rpg_sr_ore_t01",
|
|
||||||
"Schematic:sid_launcher_rocket_r_ore_t01",
|
|
||||||
"Schematic:sid_launcher_rocket_sr_ore_t01",
|
|
||||||
"Schematic:sid_launcher_rocket_vr_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_c_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_laser_sr_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_laser_vr_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_military_r_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_military_sr_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_military_vr_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_r_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_sr_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_uc_ore_t01",
|
|
||||||
"Schematic:sid_piercing_spear_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_auto_c_ore_t01",
|
|
||||||
"Schematic:sid_pistol_auto_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_auto_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_auto_uc_ore_t01",
|
|
||||||
"Schematic:sid_pistol_auto_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_autoheavy_founders_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_autoheavy_founders_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_autoheavy_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_autoheavy_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_autoheavy_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_autoheavy_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_bolt_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_bolt_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_boltrevolver_c_ore_t01",
|
|
||||||
"Schematic:sid_pistol_boltrevolver_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_boltrevolver_uc_ore_t01",
|
|
||||||
"Schematic:sid_pistol_dragon_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_dragon_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_firecracker_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_firecracker_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_firecracker_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_gatling_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_gatling_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_semi_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_semi_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_semi_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_handcannon_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_hydraulic_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_hydraulic_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_rapid_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_rapid_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_rapid_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_rapid_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_rocket_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_semiauto_c_ore_t01",
|
|
||||||
"Schematic:sid_pistol_semiauto_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_semiauto_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_semiauto_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_semiauto_uc_ore_t01",
|
|
||||||
"Schematic:sid_pistol_semiauto_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_sixshooter_c_ore_t01",
|
|
||||||
"Schematic:sid_pistol_sixshooter_r_ore_t01",
|
|
||||||
"Schematic:sid_pistol_sixshooter_uc_ore_t01",
|
|
||||||
"Schematic:sid_pistol_space_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_space_vr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_zapper_sr_ore_t01",
|
|
||||||
"Schematic:sid_pistol_zapper_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_auto_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_auto_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_auto_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_auto_uc_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_auto_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_c_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_ou_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_ou_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_ou_uc_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_ou_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_uc_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_break_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_heavy_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_longarm_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_longarm_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_minigun_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_semiauto_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_semiauto_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_semiauto_uc_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_semiauto_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_standard_c_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_standard_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_standard_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_standard_uc_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_standard_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_c_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_founders_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_founders_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_precision_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_precision_sr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_precision_vr_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_r_ore_t01",
|
|
||||||
"Schematic:sid_shotgun_tactical_uc_ore_t01",
|
|
||||||
"Schematic:sid_sniper_amr_r_ore_t01",
|
|
||||||
"Schematic:sid_sniper_amr_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_amr_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_auto_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_auto_r_ore_t01",
|
|
||||||
"Schematic:sid_sniper_auto_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_auto_uc_ore_t01",
|
|
||||||
"Schematic:sid_sniper_auto_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_boltaction_c_ore_t01",
|
|
||||||
"Schematic:sid_sniper_boltaction_r_ore_t01",
|
|
||||||
"Schematic:sid_sniper_boltaction_scope_r_ore_t01",
|
|
||||||
"Schematic:sid_sniper_boltaction_scope_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_boltaction_scope_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_boltaction_uc_ore_t01",
|
|
||||||
"Schematic:sid_sniper_hydraulic_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_hydraulic_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_shredder_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_shredder_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_c_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_founders_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_r_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_scope_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_scope_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_uc_ore_t01",
|
|
||||||
"Schematic:sid_sniper_standard_vr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_tripleshot_sr_ore_t01",
|
|
||||||
"Schematic:sid_sniper_tripleshot_vr_ore_t01",
|
|
||||||
"Schematic:sid_wall_darts_r_t01",
|
|
||||||
"Schematic:sid_wall_darts_sr_t01",
|
|
||||||
"Schematic:sid_wall_darts_uc_t01",
|
|
||||||
"Schematic:sid_wall_darts_vr_t01",
|
|
||||||
"Schematic:sid_wall_electric_r_t01",
|
|
||||||
"Schematic:sid_wall_electric_sr_t01",
|
|
||||||
"Schematic:sid_wall_electric_uc_t01",
|
|
||||||
"Schematic:sid_wall_electric_vr_t01",
|
|
||||||
"Schematic:sid_wall_launcher_r_t01",
|
|
||||||
"Schematic:sid_wall_launcher_sr_t01",
|
|
||||||
"Schematic:sid_wall_launcher_uc_t01",
|
|
||||||
"Schematic:sid_wall_launcher_vr_t01",
|
|
||||||
"Schematic:sid_wall_light_r_t01",
|
|
||||||
"Schematic:sid_wall_light_sr_t01",
|
|
||||||
"Schematic:sid_wall_light_vr_t01",
|
|
||||||
"Schematic:sid_wall_wood_spikes_c_t01",
|
|
||||||
"Schematic:sid_wall_wood_spikes_r_t01",
|
|
||||||
"Schematic:sid_wall_wood_spikes_sr_t01",
|
|
||||||
"Schematic:sid_wall_wood_spikes_uc_t01",
|
|
||||||
"Schematic:sid_wall_wood_spikes_vr_t01",
|
|
||||||
"Worker:managerdoctor_c_t01",
|
|
||||||
"Worker:managerdoctor_r_t01",
|
|
||||||
"Worker:managerdoctor_sr_kingsly_t01",
|
|
||||||
"Worker:managerdoctor_sr_noctor_t01",
|
|
||||||
"Worker:managerdoctor_sr_treky_t01",
|
|
||||||
"Worker:managerdoctor_uc_t01",
|
|
||||||
"Worker:managerdoctor_vr_t01",
|
|
||||||
"Worker:managerengineer_c_t01",
|
|
||||||
"Worker:managerengineer_r_t01",
|
|
||||||
"Worker:managerengineer_sr_countess_t01",
|
|
||||||
"Worker:managerengineer_sr_maths_t01",
|
|
||||||
"Worker:managerengineer_sr_sobs_t01",
|
|
||||||
"Worker:managerengineer_uc_t01",
|
|
||||||
"Worker:managerengineer_vr_t01",
|
|
||||||
"Worker:managerexplorer_c_t01",
|
|
||||||
"Worker:managerexplorer_r_t01",
|
|
||||||
"Worker:managerexplorer_sr_birdie_t01",
|
|
||||||
"Worker:managerexplorer_sr_eagle_t01",
|
|
||||||
"Worker:managerexplorer_sr_spacebound_t01",
|
|
||||||
"Worker:managerexplorer_uc_t01",
|
|
||||||
"Worker:managerexplorer_vr_t01",
|
|
||||||
"Worker:managergadgeteer_c_t01",
|
|
||||||
"Worker:managergadgeteer_r_t01",
|
|
||||||
"Worker:managergadgeteer_sr_fixer_t01",
|
|
||||||
"Worker:managergadgeteer_sr_flak_t01",
|
|
||||||
"Worker:managergadgeteer_sr_zapps_t01",
|
|
||||||
"Worker:managergadgeteer_uc_t01",
|
|
||||||
"Worker:managergadgeteer_vr_t01",
|
|
||||||
"Worker:managerinventor_c_t01",
|
|
||||||
"Worker:managerinventor_r_t01",
|
|
||||||
"Worker:managerinventor_sr_frequency_t01",
|
|
||||||
"Worker:managerinventor_sr_rad_t01",
|
|
||||||
"Worker:managerinventor_sr_square_t01",
|
|
||||||
"Worker:managerinventor_uc_t01",
|
|
||||||
"Worker:managerinventor_vr_t01",
|
|
||||||
"Worker:managermartialartist_c_t01",
|
|
||||||
"Worker:managermartialartist_r_t01",
|
|
||||||
"Worker:managermartialartist_sr_dragon_t01",
|
|
||||||
"Worker:managermartialartist_sr_samurai_t01",
|
|
||||||
"Worker:managermartialartist_sr_tiger_t01",
|
|
||||||
"Worker:managermartialartist_uc_t01",
|
|
||||||
"Worker:managermartialartist_vr_t01",
|
|
||||||
"Worker:managersoldier_c_t01",
|
|
||||||
"Worker:managersoldier_r_t01",
|
|
||||||
"Worker:managersoldier_sr_malcolm_t01",
|
|
||||||
"Worker:managersoldier_sr_princess_t01",
|
|
||||||
"Worker:managersoldier_sr_ramsie_t01",
|
|
||||||
"Worker:managersoldier_uc_t01",
|
|
||||||
"Worker:managersoldier_vr_t01",
|
|
||||||
"Worker:managertrainer_c_t01",
|
|
||||||
"Worker:managertrainer_r_t01",
|
|
||||||
"Worker:managertrainer_sr_jumpy_t01",
|
|
||||||
"Worker:managertrainer_sr_raider_t01",
|
|
||||||
"Worker:managertrainer_sr_yoglattes_t01",
|
|
||||||
"Worker:managertrainer_uc_t01",
|
|
||||||
"Worker:managertrainer_vr_t01",
|
|
||||||
"Worker:workerbasic_c_t01",
|
|
||||||
"Worker:workerbasic_r_t01",
|
|
||||||
"Worker:workerbasic_sr_t01",
|
|
||||||
"Worker:workerbasic_uc_t01",
|
|
||||||
"Worker:workerbasic_vr_t01",
|
|
||||||
"Worker:workerhalloween_alt_sr_t01",
|
|
||||||
"Worker:workerhalloween_c_t01",
|
|
||||||
"Worker:workerhalloween_r_t01",
|
|
||||||
"Worker:workerhalloween_sr_t01",
|
|
||||||
"Worker:workerhalloween_uc_t01",
|
|
||||||
"Worker:workerhalloween_vr_t01"
|
|
||||||
]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[]
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"friends": [],
|
|
||||||
"incoming": [],
|
|
||||||
"outgoing": [],
|
|
||||||
"suggested": [],
|
|
||||||
"blocklist": [],
|
|
||||||
"settings": {
|
|
||||||
"acceptInvites": "public"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
28
gui/assets/backend/CloudStorage/DefaultEngine.ini
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Do not remove/change, this redirects epicgames xmpp to lawinserver xmpp
|
||||||
|
[OnlineSubsystemMcp.Xmpp]
|
||||||
|
bUseSSL=false
|
||||||
|
ServerAddr="ws://127.0.0.1"
|
||||||
|
ServerPort=80
|
||||||
|
|
||||||
|
# Do not remove/change, this redirects epicgames xmpp to lawinserver xmpp
|
||||||
|
[OnlineSubsystemMcp.Xmpp Prod]
|
||||||
|
bUseSSL=false
|
||||||
|
ServerAddr="ws://127.0.0.1"
|
||||||
|
ServerPort=80
|
||||||
|
|
||||||
|
# Forces fortnite to use the v1 party system to support lawinserver xmpp
|
||||||
|
[OnlineSubsystemMcp]
|
||||||
|
bUsePartySystemV2=false
|
||||||
|
|
||||||
|
# Forces fortnite to use the v1 party system to support lawinserver xmpp
|
||||||
|
[OnlineSubsystemMcp.OnlinePartySystemMcpAdapter]
|
||||||
|
bUsePartySystemV2=false
|
||||||
|
|
||||||
|
# Fix for XMPP not working on some versions
|
||||||
|
[XMPP]
|
||||||
|
bEnableWebsockets=true
|
||||||
|
|
||||||
|
# Fix for long waiting at checking connections to datacenters on Switch & Mobile
|
||||||
|
[/Script/Qos.QosRegionManager]
|
||||||
|
NumTestsPerRegion=1
|
||||||
|
PingTimeout=0.1
|
||||||
@@ -23,3 +23,4 @@ bIsAthenaGlobalChatEnabled=true # Battle royale global chat.
|
|||||||
|
|
||||||
[/Script/FortniteGame.FortOnlineAccount]
|
[/Script/FortniteGame.FortOnlineAccount]
|
||||||
bEnableEulaCheck=false
|
bEnableEulaCheck=false
|
||||||
|
bShouldCheckIfPlatformAllowed=false
|
||||||
3
gui/assets/backend/CloudStorage/DefaultInput.ini
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[/Script/Engine.InputSettings]
|
||||||
|
+ConsoleKeys=Tilde # Enables console using the tilde key
|
||||||
|
+ConsoleKeys=F8 # Enables console using the F8 key
|
||||||
@@ -70,3 +70,10 @@ cubeSpawnDate=2020-01-01T00:00:00.000Z
|
|||||||
|
|
||||||
## Blockbuster Contest winner video at Risky Reels event. (v5.30 Only)*
|
## Blockbuster Contest winner video at Risky Reels event. (v5.30 Only)*
|
||||||
bEnableBlockbusterRiskyEvent=false
|
bEnableBlockbusterRiskyEvent=false
|
||||||
|
|
||||||
|
## Cube melting in Loot Lake event. (v5.41 Only)*
|
||||||
|
|
||||||
|
# When set to true, the cube will fall into Loot Lake and start melting on the date specified below.
|
||||||
|
# After the event, Loot Lake will remain purple in new matches.
|
||||||
|
bEnableCubeLake=false
|
||||||
|
cubeLakeDate=2020-01-01T00:00:00.000Z
|
||||||
@@ -44189,6 +44189,98 @@
|
|||||||
},
|
},
|
||||||
"quantity": 1
|
"quantity": 1
|
||||||
},
|
},
|
||||||
|
"Schematic:SID_Edged_IceSword_SR_Crystal_T05": {
|
||||||
|
"templateId": "Schematic:SID_Edged_IceSword_SR_Crystal_T05",
|
||||||
|
"attributes": {
|
||||||
|
"legacy_alterations": [],
|
||||||
|
"max_level_bonus": 0,
|
||||||
|
"level": 50,
|
||||||
|
"refund_legacy_item": false,
|
||||||
|
"item_seen": true,
|
||||||
|
"alterations": [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"xp": 0,
|
||||||
|
"refundable": false,
|
||||||
|
"alteration_base_rarities": [],
|
||||||
|
"favorite": false
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"Schematic:SID_Edged_IceSword_SR_Ore_T05": {
|
||||||
|
"templateId": "Schematic:SID_Edged_IceSword_SR_Ore_T05",
|
||||||
|
"attributes": {
|
||||||
|
"legacy_alterations": [],
|
||||||
|
"max_level_bonus": 0,
|
||||||
|
"level": 50,
|
||||||
|
"refund_legacy_item": false,
|
||||||
|
"item_seen": true,
|
||||||
|
"alterations": [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"xp": 0,
|
||||||
|
"refundable": false,
|
||||||
|
"alteration_base_rarities": [],
|
||||||
|
"favorite": false
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"Schematic:SID_Edged_IceSword_VR_Crystal_T05": {
|
||||||
|
"templateId": "Schematic:SID_Edged_IceSword_VR_Crystal_T05",
|
||||||
|
"attributes": {
|
||||||
|
"legacy_alterations": [],
|
||||||
|
"max_level_bonus": 0,
|
||||||
|
"level": 50,
|
||||||
|
"refund_legacy_item": false,
|
||||||
|
"item_seen": true,
|
||||||
|
"alterations": [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"xp": 0,
|
||||||
|
"refundable": false,
|
||||||
|
"alteration_base_rarities": [],
|
||||||
|
"favorite": false
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"Schematic:SID_Edged_IceSword_VR_Ore_T05": {
|
||||||
|
"templateId": "Schematic:SID_Edged_IceSword_VR_Ore_T05",
|
||||||
|
"attributes": {
|
||||||
|
"legacy_alterations": [],
|
||||||
|
"max_level_bonus": 0,
|
||||||
|
"level": 50,
|
||||||
|
"refund_legacy_item": false,
|
||||||
|
"item_seen": true,
|
||||||
|
"alterations": [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"xp": 0,
|
||||||
|
"refundable": false,
|
||||||
|
"alteration_base_rarities": [],
|
||||||
|
"favorite": false
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
"Schematic:Ingredient_Duct_Tape": {
|
"Schematic:Ingredient_Duct_Tape": {
|
||||||
"templateId": "Schematic:Ingredient_Duct_Tape",
|
"templateId": "Schematic:Ingredient_Duct_Tape",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"_id": "LawinServer",
|
"_id": "LawinServer",
|
||||||
"created": "0001-01-01T00:00:00.000Z",
|
"created": "0001-01-01T00:00:00.000Z",
|
||||||
"updated": "0001-01-01T00:00:00.000Z",
|
"updated": "0001-01-01T00:00:00.000Z",
|
||||||
"rvn": 1,
|
"rvn": 10,
|
||||||
"wipeNumber": 1,
|
"wipeNumber": 1,
|
||||||
"accountId": "LawinServer",
|
"accountId": "LawinServer",
|
||||||
"profileId": "profile0",
|
"profileId": "profile0",
|
||||||
@@ -35669,6 +35669,345 @@
|
|||||||
"favorite": false
|
"favorite": false
|
||||||
},
|
},
|
||||||
"quantity": 1
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"507ac4fc-4c0e-412d-8f99-b7dee58e2f76": {
|
||||||
|
"templateId": "Expedition:expedition_sea_survivorscouting_short_t01",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresRareCommando"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 120,
|
||||||
|
"expedition_min_target_power": 6,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t01_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"a4b374c2-4e4a-4d1a-b549-6e979f20b415": {
|
||||||
|
"templateId": "Expedition:expedition_sea_survivorscouting_short_t01",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 120,
|
||||||
|
"expedition_min_target_power": 6,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t01_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"d73a42be-10cc-4175-823a-b0330ebdac5e": {
|
||||||
|
"templateId": "Expedition:expedition_air_supplyrun_long_t02",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 330,
|
||||||
|
"expedition_min_target_power": 16,
|
||||||
|
"expedition_slot_id": "expedition.generation.air.t02_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"1eac710f-cf80-4de2-bc46-54426a2e3c90": {
|
||||||
|
"templateId": "Expedition:expedition_air_survivorscouting_long_t02",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresLegendaryConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 385,
|
||||||
|
"expedition_min_target_power": 19,
|
||||||
|
"expedition_slot_id": "expedition.generation.air.t02_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"fabc7237-4d92-4692-8214-82b02aac8514": {
|
||||||
|
"templateId": "Expedition:expedition_resourcerun_stone_short",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 110,
|
||||||
|
"expedition_min_target_power": 5,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t02_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"1326df1e-fe4d-44d0-aaf9-a86107ff3b76": {
|
||||||
|
"templateId": "Expedition:expedition_survivorscouting_medium_t02",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresRareConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 250,
|
||||||
|
"expedition_min_target_power": 12,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t02_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"7888975d-08d3-47c7-8c72-2adc91a0138e": {
|
||||||
|
"templateId": "Expedition:expedition_sea_supplyrun_medium_t02",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 215,
|
||||||
|
"expedition_min_target_power": 10,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t02_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"d068b9f2-429d-4d5a-9c0b-5591f13ab22e": {
|
||||||
|
"templateId": "Expedition:expedition_sea_supplyrun_medium_t02",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresLegendaryNinja"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 215,
|
||||||
|
"expedition_min_target_power": 10,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t02_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"ae374104-d124-4f8d-8d9e-6a309efe4271": {
|
||||||
|
"templateId": "Expedition:expedition_sea_survivorscouting_medium_t03",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresEpicCommando"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 370,
|
||||||
|
"expedition_min_target_power": 18,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t03_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"ca25b234-b23f-4317-a54e-ff8492f6a18b": {
|
||||||
|
"templateId": "Expedition:expedition_sea_survivorscouting_medium_t03",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 370,
|
||||||
|
"expedition_min_target_power": 18,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t03_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"35790c16-d6c8-4aac-b861-bfb6e9356f35": {
|
||||||
|
"templateId": "Expedition:expedition_air_supplyrun_long_t03",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresLegendaryConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 520,
|
||||||
|
"expedition_min_target_power": 26,
|
||||||
|
"expedition_slot_id": "expedition.generation.air.t03_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"f4f13404-6185-4f2f-8987-f65d0522cae1": {
|
||||||
|
"templateId": "Expedition:expedition_air_supplyrun_long_t03",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 520,
|
||||||
|
"expedition_min_target_power": 26,
|
||||||
|
"expedition_slot_id": "expedition.generation.air.t03_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"1ddb6b83-1687-4f17-a7f0-580b9b4a6310": {
|
||||||
|
"templateId": "Expedition:expedition_supplyrun_medium_t03",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresEpicOutlander",
|
||||||
|
"RequiresRareConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 275,
|
||||||
|
"expedition_min_target_power": 13,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t03_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"267988c1-de32-4cf5-9aeb-4270779953bc": {
|
||||||
|
"templateId": "Expedition:expedition_craftingrun_short_t03",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresRareOutlander"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 225,
|
||||||
|
"expedition_min_target_power": 11,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t03_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"c7a44a2f-173c-4aed-b229-4f9a8297d4a8": {
|
||||||
|
"templateId": "Expedition:expedition_supplyrun_long_t04",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresEpicCommando"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 685,
|
||||||
|
"expedition_min_target_power": 34,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t04_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"9bd9ec9a-2d79-451c-9b95-bfd6345c398c": {
|
||||||
|
"templateId": "Expedition:expedition_craftingrun_long_t04",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresLegendaryConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 685,
|
||||||
|
"expedition_min_target_power": 34,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t04_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"e5cdf1d3-3bab-4ab8-9bea-e225b0fb60b3": {
|
||||||
|
"templateId": "Expedition:expedition_sea_survivorscouting_long_t04",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 825,
|
||||||
|
"expedition_min_target_power": 41,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t04_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"663eb718-757b-4e86-bf0e-1002d4f11396": {
|
||||||
|
"templateId": "Expedition:expedition_sea_survivorscouting_long_t04",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 825,
|
||||||
|
"expedition_min_target_power": 41,
|
||||||
|
"expedition_slot_id": "expedition.generation.sea.t04_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"e948d68d-1c42-480c-ab10-102b16442982": {
|
||||||
|
"templateId": "Expedition:expedition_air_survivorscouting_long_t04",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresRareConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 835,
|
||||||
|
"expedition_min_target_power": 41,
|
||||||
|
"expedition_slot_id": "expedition.generation.air.t04_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"ea24aa52-dc70-41b5-ba85-83fe81f44d86": {
|
||||||
|
"templateId": "Expedition:expedition_air_supplyrun_long_t04",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 735,
|
||||||
|
"expedition_min_target_power": 36,
|
||||||
|
"expedition_slot_id": "expedition.generation.air.t04_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"0748bf5d-f770-446b-bb14-5b784b399cdd": {
|
||||||
|
"templateId": "Expedition:expedition_choppingwood_t00",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 20,
|
||||||
|
"expedition_min_target_power": 1,
|
||||||
|
"expedition_slot_id": "expedition.generation.miningore",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"ad45e99c-0f8a-4b39-abdb-d2d10daeebcf": {
|
||||||
|
"templateId": "Expedition:expedition_miningore_t00",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [
|
||||||
|
"RequiresRareConstructor"
|
||||||
|
],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 25,
|
||||||
|
"expedition_min_target_power": 1,
|
||||||
|
"expedition_slot_id": "expedition.generation.choppingwood",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"60b692b1-eae8-4029-8fb0-f7ca5aa20dfa": {
|
||||||
|
"templateId": "Expedition:expedition_resourcerun_wood_medium",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 100,
|
||||||
|
"expedition_min_target_power": 5,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t01_0",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
|
},
|
||||||
|
"4f7ffa01-e7d6-4d13-b8b9-f07e404d7128": {
|
||||||
|
"templateId": "Expedition:expedition_survivorscouting_short_t01",
|
||||||
|
"attributes": {
|
||||||
|
"expedition_expiration_end_time": "2024-05-23T15:33:33.934Z",
|
||||||
|
"expedition_criteria": [],
|
||||||
|
"level": 1,
|
||||||
|
"expedition_max_target_power": 130,
|
||||||
|
"expedition_min_target_power": 6,
|
||||||
|
"expedition_slot_id": "expedition.generation.land.t01_1",
|
||||||
|
"expedition_expiration_start_time": "2024-05-23T14:03:33.934Z"
|
||||||
|
},
|
||||||
|
"quantity": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
@@ -35793,12 +36132,12 @@
|
|||||||
"level": 10,
|
"level": 10,
|
||||||
"named_counters": {
|
"named_counters": {
|
||||||
"SubGameSelectCount_Campaign": {
|
"SubGameSelectCount_Campaign": {
|
||||||
"current_count": 0,
|
"current_count": 1,
|
||||||
"last_incremented_time": ""
|
"last_incremented_time": "2024-05-23T14:03:33.864Z"
|
||||||
},
|
},
|
||||||
"SubGameSelectCount_Athena": {
|
"SubGameSelectCount_Athena": {
|
||||||
"current_count": 0,
|
"current_count": 7,
|
||||||
"last_incremented_time": ""
|
"last_incremented_time": "2024-05-23T13:57:38.022Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"default_hero_squad_id": "",
|
"default_hero_squad_id": "",
|
||||||
@@ -35945,5 +36284,5 @@
|
|||||||
"packs_granted": 13
|
"packs_granted": 13
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commandRevision": 0
|
"commandRevision": 9
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 398 KiB After Width: | Height: | Size: 398 KiB |
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 291 KiB |