Update to fix a few issues
This commit is contained in:
parent
e2883808f4
commit
b4020a275f
9 changed files with 38 additions and 165 deletions
|
@ -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...");
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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))),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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'
|
||||||
|
|
Loading…
Reference in a new issue