Start to update stuff
This commit is contained in:
parent
110b2d150c
commit
399d884681
18 changed files with 217 additions and 240 deletions
|
@ -1,16 +1,8 @@
|
||||||
# servermanager
|
# servermanager
|
||||||
|
|
||||||
A new Flutter project.
|
A Conan Exiles server manager
|
||||||
|
|
||||||
## Getting Started
|
## Client
|
||||||
|
__________
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
Client is the software used to configure the server. It connects to, and provides an interface for managing mods, and settings.
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
5
client/lib/Constants.dart
Normal file
5
client/lib/Constants.dart
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
class Constants {
|
||||||
|
static const TITLEBAR_COLOR = Color.fromARGB(255, 97, 0, 0);
|
||||||
|
}
|
|
@ -1,25 +1,13 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:libac_flutter/nbt/NbtUtils.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/IntTag.dart';
|
||||||
import 'package:servermanager/settings.dart';
|
import 'package:servermanager/settings.dart';
|
||||||
|
|
||||||
part 'autorestart.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 3)
|
|
||||||
class AutomaticRestartInfo {
|
class AutomaticRestartInfo {
|
||||||
@HiveField(0, defaultValue: 0)
|
|
||||||
final int hours;
|
final int hours;
|
||||||
|
|
||||||
@HiveField(1, defaultValue: 0)
|
|
||||||
final int minutes;
|
final int minutes;
|
||||||
|
|
||||||
@HiveField(2, defaultValue: 0)
|
|
||||||
final int seconds;
|
final int seconds;
|
||||||
|
|
||||||
@HiveField(3, defaultValue: false)
|
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
|
|
||||||
const AutomaticRestartInfo(
|
const AutomaticRestartInfo(
|
||||||
|
@ -27,6 +15,30 @@ class AutomaticRestartInfo {
|
||||||
this.minutes = 0,
|
this.minutes = 0,
|
||||||
this.seconds = 0,
|
this.seconds = 0,
|
||||||
this.enabled = false});
|
this.enabled = false});
|
||||||
|
|
||||||
|
static AutomaticRestartInfo deserialize(CompoundTag tag) {
|
||||||
|
return AutomaticRestartInfo(
|
||||||
|
hours: tag.get(TAG_HOURS)?.asInt() ?? 12,
|
||||||
|
minutes: tag.get(TAG_MINUTES)?.asInt() ?? 0,
|
||||||
|
seconds: tag.get(TAG_SECONDS)?.asInt() ?? 0,
|
||||||
|
enabled: NbtUtils.readBoolean(tag, TAG_ENABLED));
|
||||||
|
}
|
||||||
|
|
||||||
|
CompoundTag serialize() {
|
||||||
|
CompoundTag tag = CompoundTag();
|
||||||
|
tag.put(TAG_HOURS, IntTag.valueOf(hours));
|
||||||
|
tag.put(TAG_MINUTES, IntTag.valueOf(minutes));
|
||||||
|
tag.put(TAG_SECONDS, IntTag.valueOf(seconds));
|
||||||
|
NbtUtils.writeBoolean(tag, TAG_ENABLED, enabled);
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TAG_NAME = "ari";
|
||||||
|
static const TAG_HOURS = "hours";
|
||||||
|
static const TAG_MINUTES = "minutes";
|
||||||
|
static const TAG_SECONDS = "seconds";
|
||||||
|
static const TAG_ENABLED = "enabled";
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutoRestartPage extends StatefulWidget {
|
class AutoRestartPage extends StatefulWidget {
|
||||||
|
@ -62,8 +74,8 @@ class AutoRestartState extends State<AutoRestartPage> {
|
||||||
title: Text("Automatic Restart"),
|
title: Text("Automatic Restart"),
|
||||||
backgroundColor: Color.fromARGB(255, 100, 0, 0),
|
backgroundColor: Color.fromARGB(255, 100, 0, 0),
|
||||||
),
|
),
|
||||||
body: WillPopScope(
|
body: PopScope(
|
||||||
onWillPop: () async {
|
onPopInvoked: (v) async {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context,
|
context,
|
||||||
AutomaticRestartInfo(
|
AutomaticRestartInfo(
|
||||||
|
@ -71,8 +83,6 @@ class AutoRestartState extends State<AutoRestartPage> {
|
||||||
hours: hours,
|
hours: hours,
|
||||||
minutes: minutes,
|
minutes: minutes,
|
||||||
seconds: seconds));
|
seconds: seconds));
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
import 'package:hive/hive.dart';
|
import 'package:libac_flutter/nbt/NbtUtils.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/StringTag.dart';
|
||||||
|
|
||||||
part 'credentials.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 1)
|
|
||||||
class Credentials {
|
class Credentials {
|
||||||
@HiveField(0, defaultValue: "")
|
|
||||||
String username;
|
String username;
|
||||||
|
|
||||||
@HiveField(1, defaultValue: "")
|
|
||||||
String password;
|
String password;
|
||||||
|
|
||||||
@HiveField(2, defaultValue: "")
|
|
||||||
String secret;
|
String secret;
|
||||||
|
|
||||||
@HiveField(3, defaultValue: false)
|
|
||||||
bool has_2fa = false;
|
bool has_2fa = false;
|
||||||
|
|
||||||
Credentials(
|
Credentials(
|
||||||
|
@ -21,4 +13,28 @@ class Credentials {
|
||||||
required this.password,
|
required this.password,
|
||||||
required this.secret,
|
required this.secret,
|
||||||
required this.has_2fa});
|
required this.has_2fa});
|
||||||
|
|
||||||
|
CompoundTag save() {
|
||||||
|
CompoundTag tag = CompoundTag();
|
||||||
|
tag.put(TAG_USERNAME, StringTag.valueOf(username));
|
||||||
|
tag.put(TAG_PASSWORD, StringTag.valueOf(password));
|
||||||
|
tag.put(TAG_SECRET, StringTag.valueOf(secret));
|
||||||
|
NbtUtils.writeBoolean(tag, TAG_2FA, has_2fa);
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Credentials deserialize(CompoundTag tag) {
|
||||||
|
return Credentials(
|
||||||
|
username: tag.get(TAG_USERNAME)?.asString() ?? "",
|
||||||
|
password: tag.get(TAG_PASSWORD)?.asString() ?? "",
|
||||||
|
secret: tag.get(TAG_SECRET)?.asString() ?? "",
|
||||||
|
has_2fa: NbtUtils.readBoolean(tag, TAG_2FA));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TAG_NAME = "credentials";
|
||||||
|
static const TAG_USERNAME = "username";
|
||||||
|
static const TAG_PASSWORD = "password";
|
||||||
|
static const TAG_SECRET = "secret";
|
||||||
|
static const TAG_2FA = "2fa";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// ignore_for_file: non_constant_identifier_names, prefer_typing_uninitialized_variables, prefer_const_constructors
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class InputBox extends StatelessWidget {
|
class InputBox extends StatelessWidget {
|
||||||
|
|
|
@ -3,9 +3,9 @@ import 'dart:io';
|
||||||
import 'package:crypto/crypto.dart';
|
import 'package:crypto/crypto.dart';
|
||||||
import 'package:file_selector/file_selector.dart';
|
import 'package:file_selector/file_selector.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:libac_flutter/utils/IOTools.dart';
|
||||||
import 'package:servermanager/autorestart.dart';
|
import 'package:servermanager/autorestart.dart';
|
||||||
import 'package:servermanager/mod.dart';
|
import 'package:servermanager/mod.dart';
|
||||||
import 'package:servermanager/pathtools.dart';
|
|
||||||
import 'package:servermanager/serversettings.dart';
|
import 'package:servermanager/serversettings.dart';
|
||||||
import 'package:servermanager/settings.dart';
|
import 'package:servermanager/settings.dart';
|
||||||
import 'package:servermanager/statemachine.dart';
|
import 'package:servermanager/statemachine.dart';
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||||
import 'package:file_selector/file_selector.dart';
|
import 'package:file_selector/file_selector.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:servermanager/Constants.dart';
|
||||||
import 'package:servermanager/settings.dart';
|
import 'package:servermanager/settings.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
|
@ -20,13 +21,10 @@ class HomePageState extends State<HomePage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
settings.Read();
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("Conan Exiles Server Manager"),
|
title: Text("Conan Exiles Server Manager"),
|
||||||
backgroundColor: Color.fromARGB(255, 100, 0, 0),
|
backgroundColor: Constants.TITLEBAR_COLOR),
|
||||||
),
|
|
||||||
drawer: Drawer(
|
drawer: Drawer(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
|
|
|
@ -1,23 +1,15 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:libac_flutter/packets/packets.dart';
|
||||||
|
import 'package:servermanager/Constants.dart';
|
||||||
import 'package:servermanager/autorestart.dart';
|
import 'package:servermanager/autorestart.dart';
|
||||||
import 'package:servermanager/credentials.dart';
|
|
||||||
import 'package:servermanager/game.dart';
|
import 'package:servermanager/game.dart';
|
||||||
import 'package:servermanager/home.dart';
|
import 'package:servermanager/home.dart';
|
||||||
import 'package:servermanager/mod.dart';
|
|
||||||
import 'package:servermanager/proton.dart';
|
import 'package:servermanager/proton.dart';
|
||||||
import 'package:servermanager/serversettings.dart';
|
import 'package:servermanager/serversettings.dart';
|
||||||
import 'package:servermanager/settings.dart';
|
import 'package:servermanager/settings.dart';
|
||||||
import 'package:servermanager/settingsEntry.dart';
|
|
||||||
import 'package:servermanager/steamcmd.dart';
|
import 'package:servermanager/steamcmd.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
await Hive.initFlutter();
|
|
||||||
Hive.registerAdapter(CredentialsAdapter());
|
|
||||||
Hive.registerAdapter(ModAdapter());
|
|
||||||
Hive.registerAdapter(SettingsEntryAdapter());
|
|
||||||
Hive.registerAdapter(AutomaticRestartInfoAdapter());
|
|
||||||
Hive.registerAdapter(ServerSettingsAdapter());
|
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,10 +22,8 @@ class MyApp extends StatelessWidget {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Server Manager',
|
title: 'Server Manager',
|
||||||
theme: ThemeData.dark(useMaterial3: true),
|
theme: ThemeData.dark(useMaterial3: true),
|
||||||
home: HomePage(
|
|
||||||
settings: appSettings,
|
|
||||||
),
|
|
||||||
routes: {
|
routes: {
|
||||||
|
"/": (context) => ServerPage(),
|
||||||
"/home": (context) => HomePage(settings: appSettings),
|
"/home": (context) => HomePage(settings: appSettings),
|
||||||
"/proton": (context) => Proton(settings: appSettings),
|
"/proton": (context) => Proton(settings: appSettings),
|
||||||
"/steamcmd": (context) => SteamCMD(
|
"/steamcmd": (context) => SteamCMD(
|
||||||
|
@ -48,3 +38,54 @@ class MyApp extends StatelessWidget {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ServerPage extends StatelessWidget {
|
||||||
|
TextEditingController serverIP = TextEditingController();
|
||||||
|
TextEditingController username = TextEditingController();
|
||||||
|
TextEditingController password = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text("Conan Exiles Server Manager - Login"),
|
||||||
|
backgroundColor: Constants.TITLEBAR_COLOR,
|
||||||
|
),
|
||||||
|
floatingActionButton: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
// Send login packet to server
|
||||||
|
Settings settings = Settings();
|
||||||
|
settings.client = PacketClient(serverIP.text);
|
||||||
|
},
|
||||||
|
child: Text("Login"),
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
title: Text("Server IP/FQDN"),
|
||||||
|
subtitle: TextField(
|
||||||
|
controller: serverIP,
|
||||||
|
decoration: InputDecoration(hintText: "ex. 192.168.1.100"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Username"),
|
||||||
|
subtitle: TextField(
|
||||||
|
controller: username,
|
||||||
|
decoration: InputDecoration(hintText: "the_user"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text("Password"),
|
||||||
|
subtitle: TextField(
|
||||||
|
controller: password,
|
||||||
|
decoration: InputDecoration(hintText: "pass"),
|
||||||
|
obscureText: true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,30 +1,20 @@
|
||||||
import 'package:hive/hive.dart';
|
import 'package:libac_flutter/utils/uuid/NbtUUID.dart';
|
||||||
import 'package:uuid/v4.dart';
|
import 'package:libac_flutter/utils/uuid/UUID.dart';
|
||||||
|
|
||||||
part 'mod.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 2)
|
|
||||||
class Mod {
|
class Mod {
|
||||||
@HiveField(0, defaultValue: "")
|
|
||||||
String mod_name = "";
|
String mod_name = "";
|
||||||
|
|
||||||
@HiveField(1, defaultValue: 0)
|
|
||||||
int mod_id = 0;
|
int mod_id = 0;
|
||||||
|
|
||||||
@HiveField(2, defaultValue: "")
|
|
||||||
String mod_pak = "";
|
String mod_pak = "";
|
||||||
|
|
||||||
@HiveField(3, defaultValue: "")
|
|
||||||
String mod_hash = "";
|
String mod_hash = "";
|
||||||
|
|
||||||
bool newMod = false;
|
bool newMod = false;
|
||||||
String _id = "";
|
NbtUUID _id = NbtUUID.ZERO;
|
||||||
String mod_instance_id() {
|
String mod_instance_id() {
|
||||||
if (_id.isEmpty) {
|
if (_id.toString() == NbtUUID.ZERO) {
|
||||||
_id = UuidV4().generate();
|
_id = NbtUUID.fromUUID(UUID.generate(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _id;
|
return _id.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mod(
|
Mod(
|
||||||
|
|
0
client/lib/packets/ClientPackets.dart
Normal file
0
client/lib/packets/ClientPackets.dart
Normal file
|
@ -1,67 +0,0 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
class PathHelper {
|
|
||||||
String pth = "";
|
|
||||||
PathHelper({required this.pth});
|
|
||||||
|
|
||||||
static String combine(String path1, String path2) {
|
|
||||||
return path1 + Platform.pathSeparator + path2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PathHelper builder(String startPath) {
|
|
||||||
return PathHelper(pth: startPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
PathHelper resolve(String path2) {
|
|
||||||
pth += Platform.pathSeparator + path2;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
PathHelper conditionalResolve(bool flag, String path) {
|
|
||||||
if (flag) pth += Platform.pathSeparator + path;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool deleteDirectory({bool recursive = false}) {
|
|
||||||
Directory dir = new Directory(build());
|
|
||||||
try {
|
|
||||||
dir.deleteSync(recursive: recursive);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (E) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool deleteFile() {
|
|
||||||
File file = new File(build());
|
|
||||||
try {
|
|
||||||
file.deleteSync(recursive: true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (E) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PathHelper removeDir() {
|
|
||||||
deleteDirectory(recursive: true);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
PathHelper removeFile() {
|
|
||||||
deleteFile();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
PathHelper mkdir() {
|
|
||||||
Directory dir = new Directory(build());
|
|
||||||
dir.createSync(recursive: true);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
String build() {
|
|
||||||
return pth;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +1,12 @@
|
||||||
import 'dart:ffi';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/IntTag.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/StringTag.dart';
|
||||||
|
|
||||||
part 'serversettings.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 5)
|
|
||||||
class ServerSettings {
|
class ServerSettings {
|
||||||
@HiveField(0, defaultValue: "Password01234")
|
|
||||||
final String RconPassword;
|
final String RconPassword;
|
||||||
|
|
||||||
@HiveField(1, defaultValue: 7779)
|
|
||||||
final int RconPort;
|
final int RconPort;
|
||||||
|
|
||||||
@HiveField(2, defaultValue: 7780)
|
|
||||||
final int GamePort;
|
final int GamePort;
|
||||||
|
|
||||||
@HiveField(3, defaultValue: 7782)
|
|
||||||
final int QueryPort;
|
final int QueryPort;
|
||||||
|
|
||||||
const ServerSettings(
|
const ServerSettings(
|
||||||
|
@ -25,6 +14,30 @@ class ServerSettings {
|
||||||
required this.RconPort,
|
required this.RconPort,
|
||||||
required this.GamePort,
|
required this.GamePort,
|
||||||
required this.QueryPort});
|
required this.QueryPort});
|
||||||
|
|
||||||
|
static ServerSettings deserialize(CompoundTag tag) {
|
||||||
|
return ServerSettings(
|
||||||
|
RconPassword: tag.get(TAG_PASSWORD)?.asString() ?? "",
|
||||||
|
RconPort: tag.get(TAG_RCON_PORT)?.asInt() ?? 25565,
|
||||||
|
GamePort: tag.get(TAG_GAME_PORT)?.asInt() ?? 0,
|
||||||
|
QueryPort: tag.get(TAG_QUERY_PORT)?.asInt() ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompoundTag serialize() {
|
||||||
|
CompoundTag tag = CompoundTag();
|
||||||
|
tag.put(TAG_PASSWORD, StringTag.valueOf(RconPassword));
|
||||||
|
tag.put(TAG_RCON_PORT, IntTag.valueOf(RconPort));
|
||||||
|
tag.put(TAG_GAME_PORT, IntTag.valueOf(GamePort));
|
||||||
|
tag.put(TAG_QUERY_PORT, IntTag.valueOf(QueryPort));
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TAG_NAME = "serverSettings";
|
||||||
|
static const TAG_PASSWORD = "password";
|
||||||
|
static const TAG_RCON_PORT = "rcon";
|
||||||
|
static const TAG_GAME_PORT = "game";
|
||||||
|
static const TAG_QUERY_PORT = "query";
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServerSettingsPage extends StatefulWidget {
|
class ServerSettingsPage extends StatefulWidget {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:libac_flutter/nbt/NbtIo.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||||
|
import 'package:libac_flutter/packets/packets.dart';
|
||||||
|
import 'package:libac_flutter/utils/IOTools.dart';
|
||||||
import 'package:servermanager/mod.dart';
|
import 'package:servermanager/mod.dart';
|
||||||
import 'package:servermanager/pathtools.dart';
|
|
||||||
import 'package:servermanager/settingsEntry.dart';
|
import 'package:servermanager/settingsEntry.dart';
|
||||||
import 'package:servermanager/statemachine.dart';
|
import 'package:servermanager/statemachine.dart';
|
||||||
|
|
||||||
|
@ -12,6 +14,7 @@ class Settings {
|
||||||
|
|
||||||
String steamcmd_path = "";
|
String steamcmd_path = "";
|
||||||
String game_path = "";
|
String game_path = "";
|
||||||
|
PacketClient? client;
|
||||||
|
|
||||||
StateMachine subsys = StateMachine();
|
StateMachine subsys = StateMachine();
|
||||||
|
|
||||||
|
@ -21,45 +24,43 @@ class Settings {
|
||||||
|
|
||||||
SettingsEntry? inst;
|
SettingsEntry? inst;
|
||||||
|
|
||||||
void Read() {
|
Future<void> Read() async {
|
||||||
if (!isValid()) return;
|
try {
|
||||||
var box = Hive.box("settings");
|
var tag = await NbtIo.read(
|
||||||
|
PathHelper.builder(game_path).resolve("settings.dat").build());
|
||||||
|
|
||||||
inst = box.get("entry", defaultValue: SettingsEntry()) as SettingsEntry;
|
inst = SettingsEntry.deserialize(tag.get("entry") as CompoundTag);
|
||||||
|
} catch (E) {
|
||||||
|
inst = SettingsEntry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write() {
|
void Write() {
|
||||||
if (!isValid()) return;
|
if (!isValid()) return;
|
||||||
var box = Hive.box("settings");
|
CompoundTag tag = CompoundTag();
|
||||||
box.put("entry", inst);
|
tag.put("entry", inst!.serialize());
|
||||||
|
|
||||||
box.compact();
|
NbtIo.write(
|
||||||
|
PathHelper.builder(game_path).resolve("settings.dat").build(), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValid() {
|
bool isValid() {
|
||||||
if (!Hive.isBoxOpen("settings")) {
|
if (inst == null) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Box<E>> Open<E>() {
|
Future<void> Open() async {
|
||||||
Close();
|
Close();
|
||||||
return Hive.openBox(
|
Instance.Read();
|
||||||
"settings",
|
|
||||||
path: game_path,
|
|
||||||
compactionStrategy: (entries, deletedEntries) {
|
|
||||||
return deletedEntries > 1;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Close() {
|
static void Close() async {
|
||||||
if (Hive.isBoxOpen("settings")) {
|
if (Instance.isValid()) {
|
||||||
var box = Hive.box("settings");
|
Instance.Write();
|
||||||
box.compact();
|
Instance.inst = null;
|
||||||
box.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,50 @@
|
||||||
import 'package:hive/hive.dart';
|
import 'package:libac_flutter/nbt/NbtUtils.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||||
|
import 'package:libac_flutter/nbt/impl/StringTag.dart';
|
||||||
import 'package:servermanager/autorestart.dart';
|
import 'package:servermanager/autorestart.dart';
|
||||||
import 'package:servermanager/credentials.dart';
|
import 'package:servermanager/credentials.dart';
|
||||||
import 'package:servermanager/mod.dart';
|
import 'package:servermanager/mod.dart';
|
||||||
import 'package:servermanager/serversettings.dart';
|
import 'package:servermanager/serversettings.dart';
|
||||||
|
|
||||||
part 'settingsEntry.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: 0)
|
|
||||||
class SettingsEntry {
|
class SettingsEntry {
|
||||||
@HiveField(0, defaultValue: [])
|
|
||||||
List<Mod> mods = [];
|
List<Mod> mods = [];
|
||||||
|
|
||||||
@HiveField(3)
|
|
||||||
Credentials? steam_creds;
|
Credentials? steam_creds;
|
||||||
|
|
||||||
@HiveField(4, defaultValue: AutomaticRestartInfo())
|
|
||||||
AutomaticRestartInfo timer = AutomaticRestartInfo();
|
AutomaticRestartInfo timer = AutomaticRestartInfo();
|
||||||
|
|
||||||
@HiveField(5,
|
|
||||||
defaultValue: ServerSettings(
|
|
||||||
RconPassword: "Password01234",
|
|
||||||
RconPort: 7779,
|
|
||||||
GamePort: 7780,
|
|
||||||
QueryPort: 7782))
|
|
||||||
ServerSettings serverSettings = ServerSettings(
|
ServerSettings serverSettings = ServerSettings(
|
||||||
RconPassword: "Password01234",
|
RconPassword: "Password01234",
|
||||||
RconPort: 7779,
|
RconPort: 7779,
|
||||||
GamePort: 7780,
|
GamePort: 7780,
|
||||||
QueryPort: 7782);
|
QueryPort: 7782);
|
||||||
|
|
||||||
@HiveField(6, defaultValue: true)
|
|
||||||
bool downloadMods = true;
|
bool downloadMods = true;
|
||||||
|
|
||||||
@HiveField(7, defaultValue: "")
|
|
||||||
String conanExilesLibraryPath = "";
|
String conanExilesLibraryPath = "";
|
||||||
|
|
||||||
|
static SettingsEntry deserialize(CompoundTag tag) {
|
||||||
|
SettingsEntry st = SettingsEntry();
|
||||||
|
|
||||||
|
if (tag.containsKey(Credentials.TAG_NAME))
|
||||||
|
st.steam_creds =
|
||||||
|
Credentials.deserialize(tag.get(Credentials.TAG_NAME) as CompoundTag);
|
||||||
|
st.timer = AutomaticRestartInfo.deserialize(
|
||||||
|
tag.get(AutomaticRestartInfo.TAG_NAME) as CompoundTag);
|
||||||
|
st.serverSettings = ServerSettings.deserialize(
|
||||||
|
tag.get(ServerSettings.TAG_NAME) as CompoundTag);
|
||||||
|
|
||||||
|
st.downloadMods = NbtUtils.readBoolean(tag, "download");
|
||||||
|
st.conanExilesLibraryPath = tag.get("libpath")?.asString() ?? "";
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompoundTag serialize() {
|
||||||
|
CompoundTag tag = CompoundTag();
|
||||||
|
if (steam_creds != null) tag.put(Credentials.TAG_NAME, steam_creds!.save());
|
||||||
|
tag.put(AutomaticRestartInfo.TAG_NAME, timer.serialize());
|
||||||
|
tag.put(ServerSettings.TAG_NAME, serverSettings.serialize());
|
||||||
|
NbtUtils.writeBoolean(tag, "download", downloadMods);
|
||||||
|
|
||||||
|
tag.put("libpath", StringTag.valueOf(conanExilesLibraryPath));
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:libac_flutter/utils/IOTools.dart';
|
||||||
|
import 'package:mc_rcon_dart/mc_rcon_dart.dart';
|
||||||
import 'package:servermanager/game.dart';
|
import 'package:servermanager/game.dart';
|
||||||
import 'package:servermanager/pathtools.dart';
|
|
||||||
import 'package:servermanager/proton.dart';
|
import 'package:servermanager/proton.dart';
|
||||||
import 'package:servermanager/settings.dart';
|
import 'package:servermanager/settings.dart';
|
||||||
import 'package:mc_rcon_dart/mc_rcon_dart.dart';
|
|
||||||
|
|
||||||
enum States {
|
enum States {
|
||||||
Idle, // For when the state machine is waiting for a state change
|
Idle, // For when the state machine is waiting for a state change
|
||||||
|
|
|
@ -6,9 +6,7 @@ import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
import path_provider_foundation
|
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ dependencies:
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
hive:
|
|
||||||
hive_flutter:
|
|
||||||
file_selector:
|
file_selector:
|
||||||
archive:
|
archive:
|
||||||
dio:
|
dio:
|
||||||
mc_rcon_dart:
|
mc_rcon_dart:
|
||||||
uuid: ^4.1.0
|
|
||||||
crypto:
|
crypto:
|
||||||
|
libac_flutter:
|
||||||
|
hosted: https://git.zontreck.com/api/packages/AriasCreations/pub/
|
||||||
|
version: 1.0.8
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -54,7 +54,6 @@ dev_dependencies:
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^3.0.0
|
flutter_lints: ^3.0.0
|
||||||
hive_generator:
|
|
||||||
build_runner:
|
build_runner:
|
||||||
msix: ^3.16.6
|
msix: ^3.16.6
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
// This is a basic Flutter widget test.
|
|
||||||
//
|
|
||||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
|
||||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
import 'package:servermanager/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
|
||||||
// Build our app and trigger a frame.
|
|
||||||
await tester.pumpWidget(const MyApp());
|
|
||||||
|
|
||||||
// Verify that our counter starts at 0.
|
|
||||||
expect(find.text('0'), findsOneWidget);
|
|
||||||
expect(find.text('1'), findsNothing);
|
|
||||||
|
|
||||||
// Tap the '+' icon and trigger a frame.
|
|
||||||
await tester.tap(find.byIcon(Icons.add));
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
// Verify that our counter has incremented.
|
|
||||||
expect(find.text('0'), findsNothing);
|
|
||||||
expect(find.text('1'), findsOneWidget);
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in a new issue