Update to fix a few issues

This commit is contained in:
zontreck 2024-08-28 11:30:57 -07:00
parent e2883808f4
commit b4020a275f
9 changed files with 38 additions and 165 deletions

View file

@ -18,7 +18,7 @@ void main() async {
await settings.Read(); await settings.Read();
print( print(
"Server Admin Credentials\nUsername: ${settings.serverLoginCreds.username}\nPassword: ${settings.serverLoginCreds.password}\n\n"); "Server Admin Credentials\nUsername: ${settings.superuser.name}\nPassword (Default): changeMe123\n\n");
PathHelper helper = PathHelper(pth: Directory.current.path); PathHelper helper = PathHelper(pth: Directory.current.path);
helper = helper.resolve("data").mkdir(); helper = helper.resolve("data").mkdir();
@ -33,22 +33,26 @@ void main() async {
print("Setup of local system variables completed"); print("Setup of local system variables completed");
if (settings.FTS) {
Settings.Clear(); // Initialize the super-user account
print("Super-User Account initialized with default credentials");
settings.server = true;
}
settings.Write(); settings.Write();
print("Wrote settings.dat"); print("Wrote settings.dat");
if (settings.FTS)
settings.superuser = User.make(
settings.serverLoginCreds.username,
settings.serverLoginCreds.password,
UserLevel.Super_User); // Initialize the super-user account
print("Initializing SteamCMD"); print("Initializing SteamCMD");
await settings.initializeSteamCmd(); await settings.initializeSteamCmd();
print("Initialized Steamcmd"); print("Initialized Steamcmd");
print("Running winetricks"); print("Running winetricks");
//if (!Directory(settings.getWinePrefixPath()).existsSync()) if (!settings.wineInitialized) {
// await settings.initializeWine(); await settings.initializeWine();
settings.wineInitialized = true;
settings.Write();
}
print("Finished installing needed DLLs"); print("Finished installing needed DLLs");
print("Checking for game server updates..."); print("Checking for game server updates...");

View file

@ -7,7 +7,6 @@ import 'package:servermanager/pages/DiscordConfigPage.dart';
import 'package:servermanager/pages/GameServerPage.dart'; import 'package:servermanager/pages/GameServerPage.dart';
import 'package:servermanager/pages/ModManager.dart'; import 'package:servermanager/pages/ModManager.dart';
import 'package:servermanager/pages/autorestart.dart'; import 'package:servermanager/pages/autorestart.dart';
import 'package:servermanager/pages/credentials_prompt.dart';
import 'package:servermanager/pages/home.dart'; import 'package:servermanager/pages/home.dart';
import 'package:servermanager/pages/snapshots.dart'; import 'package:servermanager/pages/snapshots.dart';
import 'package:servermanager/structs/settings.dart'; import 'package:servermanager/structs/settings.dart';
@ -30,7 +29,6 @@ class MyApp extends StatelessWidget {
routes: { routes: {
"/": (context) => ServerPage(), "/": (context) => ServerPage(),
"/home": (context) => HomePage(settings: appSettings), "/home": (context) => HomePage(settings: appSettings),
"/creds": (context) => CredentialsPage(),
"/acl": (context) => AccessControlListPage(), "/acl": (context) => AccessControlListPage(),
"/acl/edit": (context) => ACLEdit(), "/acl/edit": (context) => ACLEdit(),
"/server": (context) => GameServerPage(settings: appSettings), "/server": (context) => GameServerPage(settings: appSettings),

View file

@ -76,6 +76,7 @@ class ACLEditorState extends State<ACLEdit> {
var newUser = false; var newUser = false;
TextEditingController username = TextEditingController(); TextEditingController username = TextEditingController();
TextEditingController password = TextEditingController(); TextEditingController password = TextEditingController();
var canDelete = true;
User? current; User? current;
@ -84,11 +85,15 @@ class ACLEditorState extends State<ACLEdit> {
var args = ModalRoute.of(context)!.settings.arguments; var args = ModalRoute.of(context)!.settings.arguments;
if (args == null) { if (args == null) {
newUser = true; newUser = true;
canDelete = false;
} else { } else {
User usr = args as User; User usr = args as User;
username.text = usr.name; username.text = usr.name;
current = usr; current = usr;
canDelete = true;
if (usr.permissions == UserLevel.Super_User) canDelete = false;
} }
setState(() {}); setState(() {});
@ -186,7 +191,7 @@ class ACLEditorState extends State<ACLEdit> {
SizedBox( SizedBox(
height: 50, height: 50,
), ),
if (!newUser) if (canDelete)
ListTile( ListTile(
title: Text("DELETE USER"), title: Text("DELETE USER"),
leading: Icon(Icons.delete), leading: Icon(Icons.delete),

View file

@ -1,100 +0,0 @@
import 'package:flutter/material.dart';
import 'package:servermanager/structs/credentials.dart';
class CredentialsPage extends StatefulWidget {
@override
CredentialsPrompt createState() => CredentialsPrompt();
}
// Returns a Credentials Object
class CredentialsPrompt extends State<CredentialsPage> {
TextEditingController username = TextEditingController();
TextEditingController password = TextEditingController();
bool initialInitDone = false;
@override
void initState() {}
@override
void didChangeDependencies() {
final args = ModalRoute.of(context)!.settings.arguments as Credentials?;
if (args != null) {
if (!initialInitDone) {
username.text = args.username;
password.text = args.password;
initialInitDone = true;
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Conan Exiles Server Manager - Credentials"),
backgroundColor: Color.fromARGB(255, 100, 0, 0),
),
floatingActionButton: ElevatedButton(
child: Text("Save"),
onPressed: () {
Navigator.pop(
context,
Credentials(
username: username.text,
password: password.text,
));
},
),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
children: [
Row(
children: [
SizedBox(
width: 150,
child: Row(
children: [
Icon(Icons.person),
Text("Username:"),
],
)),
Expanded(
child: TextField(
controller: username,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4))),
),
)
],
),
SizedBox(
height: 16,
),
Row(
children: [
SizedBox(
width: 150,
child: Row(
children: [
Icon(Icons.key),
Text("Password:"),
],
)),
Expanded(
child: TextField(
controller: password,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4))),
),
)
],
),
],
)));
}
}

View file

@ -97,11 +97,14 @@ class HomePageState extends State<HomePage> {
Text("Edit ServerManager credentials (SUPER USER ONLY)"), Text("Edit ServerManager credentials (SUPER USER ONLY)"),
leading: Icon(Icons.key), leading: Icon(Icons.key),
onTap: () async { onTap: () async {
var reply = await Navigator.pushNamed(context, "/creds", if (settings.loggedInUser!.permissions ==
arguments: settings.superuser.name); UserLevel.Super_User) {
if (reply != null) { var reply = await Navigator.pushNamed(context, "/acl/edit",
Credentials creds = reply as Credentials; arguments: settings.superuser);
settings.serverLoginCreds = creds; if (reply != null) {
var creds = reply as User;
settings.superuser = creds;
}
} }
}, },
), ),

View file

@ -5,34 +5,6 @@ import 'package:libac_dart/utils/Hashing.dart';
import 'package:servermanager/structs/discordHookHelper.dart'; import 'package:servermanager/structs/discordHookHelper.dart';
import 'package:servermanager/structs/settings.dart'; import 'package:servermanager/structs/settings.dart';
class Credentials {
String username;
String password;
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));
return tag;
}
static Credentials deserialize(CompoundTag tag) {
return Credentials(
username: tag.get(TAG_USERNAME)?.asString() ?? "",
password: tag.get(TAG_PASSWORD)?.asString() ?? "");
}
static const TAG_NAME = "credentials";
static const TAG_USERNAME = "username";
static const TAG_PASSWORD = "password";
}
class User { class User {
String name; String name;
String passwordHash; String passwordHash;

View file

@ -29,14 +29,13 @@ class Settings {
static final Settings Instance = Settings._(); static final Settings Instance = Settings._();
bool server = true; bool server = true;
bool wineInitialized = false;
String steamcmd_path = ""; String steamcmd_path = "";
String game_path = ""; String game_path = "";
String base_path = ""; String base_path = "";
String gameServerDBFile = ""; String gameServerDBFile = "";
bool FTS = true; bool FTS = true;
Credentials serverLoginCreds =
Credentials(username: "admin", password: "changeMe123");
UUID remoteLoginToken = UUID.ZERO; UUID remoteLoginToken = UUID.ZERO;
PacketClient? client; PacketClient? client;
@ -57,8 +56,8 @@ class Settings {
tag.put("base", StringTag.valueOf(base_path)); tag.put("base", StringTag.valueOf(base_path));
tag.put("dbfile", StringTag.valueOf(getWorldGameDB())); tag.put("dbfile", StringTag.valueOf(getWorldGameDB()));
NbtUtils.writeBoolean(tag, "fts", FTS); NbtUtils.writeBoolean(tag, "fts", FTS);
NbtUtils.writeBoolean(tag, "wine_init", wineInitialized);
tag.put("server_creds", serverLoginCreds.save());
tag.put("superuser", superuser.serialize()); tag.put("superuser", superuser.serialize());
NbtUtils.writeUUID(tag, "token", NbtUUID.fromUUID(remoteLoginToken)); NbtUtils.writeUUID(tag, "token", NbtUUID.fromUUID(remoteLoginToken));
@ -86,8 +85,7 @@ class Settings {
FTS = NbtUtils.readBoolean(tag, "fts"); // First Time Setup. 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 // FTS should be disabled by the client when sending it back to the server in a C2SApplySettingsPacket
serverLoginCreds = superuser = User.deserialize(tag.get("superuser")!.asCompoundTag());
Credentials.deserialize(tag.get("server_creds")!.asCompoundTag());
if (tag.containsKey("main")) { if (tag.containsKey("main")) {
inst = SettingsEntry.deserialize(tag.get("main")!.asCompoundTag()); inst = SettingsEntry.deserialize(tag.get("main")!.asCompoundTag());
@ -102,21 +100,13 @@ class Settings {
var tag = await NbtIo.read("settings.dat"); var tag = await NbtIo.read("settings.dat");
inst = SettingsEntry.deserialize(tag.get("entry") as CompoundTag); inst = SettingsEntry.deserialize(tag.get("entry") as CompoundTag);
serverLoginCreds = Credentials.deserialize( wineInitialized = NbtUtils.readBoolean(tag, "wine_init");
tag.get(Credentials.TAG_NAME)!.asCompoundTag());
FTS = NbtUtils.readBoolean(tag, "fts"); FTS = NbtUtils.readBoolean(tag, "fts");
} catch (E) { } catch (E) {
print("No existing settings file found, initializing default settings"); print("No existing settings file found, initializing default settings");
inst = SettingsEntry(); inst = SettingsEntry();
inst!.steam_creds = Credentials(
username: "",
password: "",
);
serverLoginCreds = Credentials( superuser = User.make("admin", "changeMe123", UserLevel.Super_User);
username: "admin",
password: "changeMe123",
);
FTS = true; FTS = true;
} }
} }
@ -128,8 +118,9 @@ class Settings {
if (inst == null) return; if (inst == null) return;
CompoundTag tag = CompoundTag(); CompoundTag tag = CompoundTag();
tag.put("entry", inst!.serialize()); tag.put("entry", inst!.serialize());
tag.put(Credentials.TAG_NAME, serverLoginCreds.save()); tag.put("superuser", superuser.serialize());
NbtUtils.writeBoolean(tag, "fts", FTS); NbtUtils.writeBoolean(tag, "fts", FTS);
NbtUtils.writeBoolean(tag, "wine_init", wineInitialized);
NbtIo.write("settings.dat", tag); NbtIo.write("settings.dat", tag);
} }
@ -319,7 +310,6 @@ class Settings {
Future<void> initializeWine() async { Future<void> initializeWine() async {
await runWinetrick("win10"); await runWinetrick("win10");
await runWinetrick("w_workaround_wine_bug-50894");
await runWinetrick("cmd"); await runWinetrick("cmd");
await runWinetrick("vcrun2013"); await runWinetrick("vcrun2013");
await runWinetrick("vcrun2015"); await runWinetrick("vcrun2015");
@ -413,7 +403,8 @@ class Settings {
static void Clear() { static void Clear() {
Instance.inst = SettingsEntry(); Instance.inst = SettingsEntry();
Instance.subsys = StateMachine(); Instance.subsys = StateMachine();
Instance.serverLoginCreds = Credentials(username: "admin", password: ""); Instance.superuser =
User.make("admin", "changeMe123", UserLevel.Super_User);
Instance.server = false; Instance.server = false;
} }
} }

View file

@ -15,7 +15,7 @@ class SettingsEntry {
DiscordHookProps discord = DiscordHookProps discord =
DiscordHookProps(url: "", serverName: "", enabled: false); DiscordHookProps(url: "", serverName: "", enabled: false);
Credentials? steam_creds;
bool pterodactylMode = true; // Default is to be compatible bool pterodactylMode = true; // Default is to be compatible
AutomaticRestartInfo timer = AutomaticRestartInfo timer =
AutomaticRestartInfo(time: Time(hours: 0, minutes: 0, seconds: 0)); AutomaticRestartInfo(time: Time(hours: 0, minutes: 0, seconds: 0));

View file

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.1.0+36 version: 1.1.0+39
environment: environment:
sdk: '>=3.1.4 <4.0.0' sdk: '>=3.1.4 <4.0.0'