Got more things functional
This commit is contained in:
parent
a1141cd2b8
commit
fc0c1c7e7a
23 changed files with 1080 additions and 876 deletions
18
lib/structs/SessionData.dart
Normal file
18
lib/structs/SessionData.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
import 'package:libac_flutter/utils/TimeUtils.dart';
|
||||
import 'package:servermanager/statemachine.dart';
|
||||
|
||||
class SessionData {
|
||||
static bool shutdownPending = false;
|
||||
|
||||
/// This flag will track the number of seconds until restart
|
||||
///
|
||||
/// This is initialized initially based on the AutomaticRestart timer if enabled.
|
||||
///
|
||||
/// This may be updated to one to two minutes by a Mod Update, or Wrapper update
|
||||
static Time timer = Time(hours: 0, minutes: 0, seconds: 0);
|
||||
static Time operating_time = Time(hours: 0, minutes: 0, seconds: 0);
|
||||
|
||||
static String shutdownMessage = "";
|
||||
|
||||
static WarnIntervals CURRENT_INTERVAL = WarnIntervals.NONE;
|
||||
}
|
|
@ -1,32 +1,28 @@
|
|||
import 'package:libac_flutter/nbt/NbtUtils.dart';
|
||||
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||
import 'package:libac_flutter/nbt/impl/IntTag.dart';
|
||||
import 'package:libac_flutter/utils/TimeUtils.dart';
|
||||
|
||||
class AutomaticRestartInfo {
|
||||
final int hours;
|
||||
final int minutes;
|
||||
final int seconds;
|
||||
Time time = Time(hours: 0, minutes: 0, seconds: 0);
|
||||
final bool enabled;
|
||||
|
||||
const AutomaticRestartInfo(
|
||||
{this.hours = 0,
|
||||
this.minutes = 0,
|
||||
this.seconds = 0,
|
||||
this.enabled = false});
|
||||
AutomaticRestartInfo({required this.time, 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,
|
||||
time: Time(
|
||||
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));
|
||||
tag.put(TAG_HOURS, IntTag.valueOf(time.hours));
|
||||
tag.put(TAG_MINUTES, IntTag.valueOf(time.minutes));
|
||||
tag.put(TAG_SECONDS, IntTag.valueOf(time.seconds));
|
||||
NbtUtils.writeBoolean(tag, TAG_ENABLED, enabled);
|
||||
|
||||
return tag;
|
||||
|
|
|
@ -1,25 +1,19 @@
|
|||
import 'package:libac_flutter/nbt/NbtUtils.dart';
|
||||
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||
import 'package:libac_flutter/nbt/impl/StringTag.dart';
|
||||
|
||||
class Credentials {
|
||||
String username;
|
||||
String password;
|
||||
String secret;
|
||||
bool has_2fa = false;
|
||||
|
||||
Credentials(
|
||||
{required this.username,
|
||||
required this.password,
|
||||
required this.secret,
|
||||
required this.has_2fa});
|
||||
Credentials({
|
||||
required this.username,
|
||||
required this.password,
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -27,14 +21,10 @@ class Credentials {
|
|||
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));
|
||||
password: tag.get(TAG_PASSWORD)?.asString() ?? "");
|
||||
}
|
||||
|
||||
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,4 +1,6 @@
|
|||
import 'package:libac_flutter/utils/uuid/NbtUUID.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';
|
||||
import 'package:libac_flutter/utils/uuid/UUID.dart';
|
||||
|
||||
class Mod {
|
||||
|
@ -8,10 +10,10 @@ class Mod {
|
|||
String mod_hash = "";
|
||||
|
||||
bool newMod = false;
|
||||
NbtUUID _id = NbtUUID.ZERO;
|
||||
UUID _id = UUID.ZERO;
|
||||
String mod_instance_id() {
|
||||
if (_id.toString() == NbtUUID.ZERO) {
|
||||
_id = NbtUUID.fromUUID(UUID.generate(4));
|
||||
if (_id.toString() == UUID.ZERO.toString()) {
|
||||
_id = UUID.generate(4);
|
||||
}
|
||||
|
||||
return _id.toString();
|
||||
|
@ -23,4 +25,24 @@ class Mod {
|
|||
this.newMod = false,
|
||||
this.mod_pak = "Not Initialized",
|
||||
this.mod_hash = ""});
|
||||
|
||||
CompoundTag serialize() {
|
||||
CompoundTag tag = CompoundTag();
|
||||
tag.put("name", StringTag.valueOf(mod_name));
|
||||
tag.put("id", IntTag.valueOf(mod_id));
|
||||
tag.put("pak", StringTag.valueOf(mod_pak));
|
||||
tag.put("hash", StringTag.valueOf(mod_hash));
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
static Mod deserialize(CompoundTag tag) {
|
||||
CompoundTag ct = tag as CompoundTag;
|
||||
|
||||
return Mod(
|
||||
mod_name: ct.get("name")!.asString(),
|
||||
mod_id: ct.get("id")!.asInt(),
|
||||
mod_pak: ct.get("pak")!.asString(),
|
||||
mod_hash: ct.get("hash")!.asString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,19 @@ import 'package:dio/dio.dart';
|
|||
import 'package:libac_flutter/nbt/NbtIo.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:libac_flutter/packets/packets.dart';
|
||||
import 'package:libac_flutter/utils/IOTools.dart';
|
||||
import 'package:libac_flutter/utils/uuid/NbtUUID.dart';
|
||||
import 'package:libac_flutter/utils/uuid/UUID.dart';
|
||||
import 'package:rcon/rcon.dart';
|
||||
import 'package:servermanager/statemachine.dart';
|
||||
import 'package:servermanager/structs/credentials.dart';
|
||||
import 'package:servermanager/structs/mod.dart';
|
||||
import 'package:servermanager/structs/settingsEntry.dart';
|
||||
|
||||
import '../proton.dart';
|
||||
|
||||
class Settings {
|
||||
final String windows =
|
||||
"https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip";
|
||||
|
@ -28,13 +33,15 @@ class Settings {
|
|||
Settings._();
|
||||
static final Settings Instance = Settings._();
|
||||
|
||||
bool server = true;
|
||||
|
||||
String steamcmd_path = "";
|
||||
String game_path = "";
|
||||
String proton_path = "";
|
||||
String base_path = "";
|
||||
bool FTS = true;
|
||||
Credentials serverLoginCreds = Credentials(
|
||||
username: "admin", password: "changeMe123", secret: "", has_2fa: false);
|
||||
Credentials serverLoginCreds =
|
||||
Credentials(username: "admin", password: "changeMe123");
|
||||
UUID remoteLoginToken = UUID.ZERO;
|
||||
|
||||
PacketClient? client;
|
||||
|
@ -45,9 +52,50 @@ class Settings {
|
|||
return Instance;
|
||||
}
|
||||
|
||||
CompoundTag serialize() {
|
||||
CompoundTag tag = CompoundTag();
|
||||
tag.put("steamcmd", StringTag.valueOf(steamcmd_path));
|
||||
tag.put("game", StringTag.valueOf(game_path));
|
||||
tag.put("proton", StringTag.valueOf(proton_path));
|
||||
tag.put("base", StringTag.valueOf(base_path));
|
||||
NbtUtils.writeBoolean(tag, "fts", FTS);
|
||||
|
||||
tag.put("server_creds", serverLoginCreds.save());
|
||||
NbtUtils.writeUUID(tag, "token", NbtUUID.fromUUID(remoteLoginToken));
|
||||
|
||||
if (inst != null) tag.put("main", inst!.serialize());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
void deserialize(CompoundTag tag) {
|
||||
// Verify Remote Login Token
|
||||
UUID ID = NbtUtils.readUUID(tag, "token").toUUID();
|
||||
if (ID.toString() != remoteLoginToken.toString()) {
|
||||
// Invalid session
|
||||
print(
|
||||
"Invalid login session detected, or two admins are connected at once");
|
||||
}
|
||||
|
||||
steamcmd_path = tag.get("steamcmd")!.asString();
|
||||
game_path = tag.get("game")!.asString();
|
||||
proton_path = tag.get("proton")!.asString();
|
||||
base_path = tag.get("proton")!.asString();
|
||||
FTS = NbtUtils.readBoolean(tag, "fts"); // First Time Setup.
|
||||
// FTS should be disabled by the client when sending it back to the server in a C2SApplySettingsPacket
|
||||
|
||||
serverLoginCreds =
|
||||
Credentials.deserialize(tag.get("server_creds")!.asCompoundTag());
|
||||
|
||||
if (tag.containsKey("main")) {
|
||||
inst = SettingsEntry.deserialize(tag.get("main")!.asCompoundTag());
|
||||
}
|
||||
}
|
||||
|
||||
SettingsEntry? inst;
|
||||
|
||||
Future<void> Read() async {
|
||||
if (!server) return;
|
||||
try {
|
||||
var tag = await NbtIo.read("settings.dat");
|
||||
|
||||
|
@ -58,19 +106,23 @@ class Settings {
|
|||
} catch (E) {
|
||||
print("No existing settings file found, initializing default settings");
|
||||
inst = SettingsEntry();
|
||||
inst!.steam_creds =
|
||||
Credentials(username: "", password: "", secret: "", has_2fa: false);
|
||||
inst!.steam_creds = Credentials(
|
||||
username: "",
|
||||
password: "",
|
||||
);
|
||||
|
||||
serverLoginCreds = Credentials(
|
||||
username: "admin",
|
||||
password: "changeMe123",
|
||||
secret: "",
|
||||
has_2fa: false);
|
||||
username: "admin",
|
||||
password: "changeMe123",
|
||||
);
|
||||
FTS = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Write() {
|
||||
if (!server) {
|
||||
return; // safeguard against writing to a settings file on the client
|
||||
}
|
||||
if (inst == null) return;
|
||||
CompoundTag tag = CompoundTag();
|
||||
tag.put("entry", inst!.serialize());
|
||||
|
@ -110,10 +162,6 @@ class Settings {
|
|||
return steamcmd_path;
|
||||
}
|
||||
|
||||
String getSteamCmd2FA() {
|
||||
return "$steamcmd_path${Platform.pathSeparator}steamcmd-2fa${Platform.isWindows ? ".exe" : ""}";
|
||||
}
|
||||
|
||||
String getModPath() {
|
||||
return PathHelper(pth: base_path).resolve("mods").build();
|
||||
}
|
||||
|
@ -180,8 +228,9 @@ class Settings {
|
|||
|
||||
if (await dir.exists()) {
|
||||
return;
|
||||
} else
|
||||
} else {
|
||||
await dir.create(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
File getModListFile() {
|
||||
|
@ -204,7 +253,7 @@ class Settings {
|
|||
.resolve("content")
|
||||
.resolve("440900")
|
||||
.resolve("${mod.mod_id}")
|
||||
.resolve("${mod.mod_pak}")
|
||||
.resolve(mod.mod_pak)
|
||||
.build();
|
||||
if (Platform.isWindows) {
|
||||
paths.add(pth);
|
||||
|
@ -220,6 +269,18 @@ class Settings {
|
|||
flush: true, mode: FileMode.writeOnly);
|
||||
}
|
||||
|
||||
Future<void> initializeProtonPrefix() async {
|
||||
runProton("echo", ["hello"]);
|
||||
}
|
||||
|
||||
Future<String> sendRconCommand(String command) async {
|
||||
Client cli =
|
||||
await Client.create("127.0.0.1", inst!.serverSettings.RconPort);
|
||||
Message msg = Message.create(cli, PacketType.command, command);
|
||||
|
||||
return cli.send(msg).payload;
|
||||
}
|
||||
|
||||
Future<void> initializeProton() async {
|
||||
Dio dio = Dio();
|
||||
print("Downloading proton...");
|
||||
|
@ -257,7 +318,7 @@ class Settings {
|
|||
|
||||
if (Platform.isWindows) {
|
||||
// Download zip file
|
||||
final path = "${steamcmd_path}${Platform.pathSeparator}windows.zip";
|
||||
final path = "$steamcmd_path${Platform.pathSeparator}windows.zip";
|
||||
final reply = await dio.download(windows, path);
|
||||
|
||||
final bytes = File(path).readAsBytesSync();
|
||||
|
@ -283,7 +344,7 @@ class Settings {
|
|||
print("Completed.");
|
||||
} else {
|
||||
// Download tgz file
|
||||
final path = "${steamcmd_path}${Platform.pathSeparator}linux.tgz";
|
||||
final path = "$steamcmd_path${Platform.pathSeparator}linux.tgz";
|
||||
final reply = await dio.download(linux, path);
|
||||
|
||||
final bytes = File(path).readAsBytesSync();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:libac_flutter/nbt/NbtUtils.dart';
|
||||
import 'package:libac_flutter/nbt/Tag.dart';
|
||||
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
|
||||
import 'package:libac_flutter/nbt/impl/StringTag.dart';
|
||||
import 'package:libac_flutter/nbt/impl/ListTag.dart';
|
||||
import 'package:libac_flutter/utils/TimeUtils.dart';
|
||||
import 'package:servermanager/structs/autorestarts.dart';
|
||||
import 'package:servermanager/structs/credentials.dart';
|
||||
import 'package:servermanager/structs/mod.dart';
|
||||
|
@ -9,29 +11,37 @@ import 'package:servermanager/structs/serversettings.dart';
|
|||
class SettingsEntry {
|
||||
List<Mod> mods = [];
|
||||
Credentials? steam_creds;
|
||||
AutomaticRestartInfo timer = AutomaticRestartInfo();
|
||||
bool pterodactylMode = true; // Default is to be compatible
|
||||
AutomaticRestartInfo timer =
|
||||
AutomaticRestartInfo(time: Time(hours: 0, minutes: 0, seconds: 0));
|
||||
ServerSettings serverSettings = ServerSettings(
|
||||
RconPassword: "Password01234",
|
||||
RconPort: 7779,
|
||||
GamePort: 7780,
|
||||
QueryPort: 7782);
|
||||
|
||||
bool downloadMods = true;
|
||||
String conanExilesLibraryPath = "";
|
||||
|
||||
static SettingsEntry deserialize(CompoundTag tag) {
|
||||
SettingsEntry st = SettingsEntry();
|
||||
|
||||
if (tag.containsKey(Credentials.TAG_NAME))
|
||||
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() ?? "";
|
||||
if (tag.containsKey("pterodactyl")) {
|
||||
st.pterodactylMode = NbtUtils.readBoolean(tag, "pterodactyl");
|
||||
}
|
||||
|
||||
st.mods.clear();
|
||||
ListTag lMods = tag.get("mods") as ListTag;
|
||||
for (Tag tag in lMods.value) {
|
||||
CompoundTag cTag = tag.asCompoundTag();
|
||||
st.mods.add(Mod.deserialize(cTag));
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
@ -41,9 +51,13 @@ class SettingsEntry {
|
|||
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);
|
||||
NbtUtils.writeBoolean(tag, "pterodactyl", pterodactylMode);
|
||||
|
||||
tag.put("libpath", StringTag.valueOf(conanExilesLibraryPath));
|
||||
ListTag lMods = ListTag();
|
||||
for (Mod mod in mods) {
|
||||
lMods.add(mod.serialize());
|
||||
}
|
||||
tag.put("mods", lMods);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue