Move code for downloading mods into a more universal function

This commit is contained in:
zontreck 2023-11-04 16:55:13 -07:00
parent 0cf1f6b090
commit 8162dbe97a

View file

@ -7,6 +7,87 @@ import 'package:servermanager/mod.dart';
import 'package:servermanager/pathtools.dart';
import 'package:servermanager/settings.dart';
Future<void> doDownloadMods(String modsFolder) async {
Settings settings = Settings();
// Now, invoke SteamCmd to download the workshop mods. This is an authenticated action, and does require Scmd2fa
var result = await Process.run(settings.getSteamCmd2FA(),
["--raw", "--secret", settings.inst!.steam_creds!.secret]);
var code = result.stdout as String;
// Build download command
List<String> manifest = [
"+@sSteamCmdForcePlatformType",
"windows",
"+force_install_dir",
modsFolder,
"+login",
settings.inst!.steam_creds!.username,
settings.inst!.steam_creds!.password,
code.trim()
];
for (Mod M in settings.inst!.mods) {
manifest.add("+workshop_download_item");
manifest.add("440900");
manifest.add("${M.mod_id}");
}
await settings.createModFolderIfNotExists();
manifest.add("+quit");
//print(
// "Running command: ${settings.getSteamCmd()} ${manifest.join(" ")}");
result = await Process.run(settings.getSteamCmd(), manifest);
print(result.stdout);
}
Future<List<Mod>> doScanMods(String modsFolder) async {
Settings settings = Settings();
List<Mod> ret = [];
for (Mod M in settings.inst!.mods.toList()) {
var index = settings.inst!.mods.indexOf(M);
// Assemble final path.
String modsPath = PathHelper.builder(settings.game_path)
.resolve("mods")
.resolve("steamapps")
.resolve("workshop")
.resolve("content")
.resolve("440900")
.resolve("${M.mod_id}")
.build();
Directory dir = Directory(modsPath);
await for (var entity in dir.list()) {
if (entity is File && entity.path.endsWith("pak")) {
String name = entity.path.split(Platform.pathSeparator).last;
var content = await entity.readAsBytes();
var data = md5.convert(content);
var hash = data.toString();
M.mod_pak = name;
M.mod_hash = hash;
print("Discovered mod file: ${name}");
print("Hash: ${hash}");
// Update the mod instance, and retain the original modlist order
ret.add(Mod(
mod_hash: hash,
mod_id: M.mod_id,
mod_pak: name,
mod_name: M.mod_name));
}
}
}
return ret;
}
class GameServerPage extends StatefulWidget {
Settings settings;
GameServerPage({super.key, required this.settings});
@ -100,49 +181,11 @@ class GameServerPageState extends State<GameServerPage> {
subtitle: Text("Downloads the mods"),
leading: Icon(Icons.download_sharp),
onTap: () async {
// Triggers the download status
setState(() {
downloading = true;
});
await doDownloadMods(settings.getModPath());
// Now, invoke SteamCmd to download the workshop mods. This is an authenticated action, and does require Scmd2fa
var result = await Process.run(settings.getSteamCmd2FA(), [
"--raw",
"--secret",
settings.inst!.steam_creds!.secret
]);
var code = result.stdout as String;
// Build download command
List<String> manifest = [
"+@sSteamCmdForcePlatformType",
"windows",
"+force_install_dir",
settings.getModPath(),
"+login",
settings.inst!.steam_creds!.username,
settings.inst!.steam_creds!.password,
code.trim()
];
for (Mod M in settings.inst!.mods) {
manifest.add("+workshop_download_item");
manifest.add("440900");
manifest.add("${M.mod_id}");
}
await settings.createModFolderIfNotExists();
manifest.add("+quit");
//print(
// "Running command: ${settings.getSteamCmd()} ${manifest.join(" ")}");
result =
await Process.run(settings.getSteamCmd(), manifest);
print(result.stdout);
// Unset downloading
setState(() {
downloading = false;
});
@ -150,58 +193,26 @@ class GameServerPageState extends State<GameServerPage> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Scanning mods...")));
for (Mod M in settings.inst!.mods.toList()) {
var index = settings.inst!.mods.indexOf(M);
// Assemble final path.
String modsPath = PathHelper.builder(settings.game_path)
.resolve("mods")
.resolve("steamapps")
.resolve("workshop")
.resolve("content")
.resolve("440900")
.resolve("${M.mod_id}")
.build();
Directory dir = Directory(modsPath);
await for (var entity in dir.list()) {
if (entity is File && entity.path.endsWith("pak")) {
String name =
entity.path.split(Platform.pathSeparator).last;
var content = await entity.readAsBytes();
var data = md5.convert(content);
var hash = data.toString();
M.mod_pak = name;
M.mod_hash = hash;
print("Discovered mod file: ${name}");
print("Hash: ${hash}");
// Update the mod instance
var mods = await doScanMods(settings.getModPath());
setState(() {
settings.inst!.mods[index] = Mod(
mod_hash: hash,
mod_id: M.mod_id,
mod_pak: name,
mod_name: M.mod_name);
});
}
}
}
settings.inst!.mods = mods;
setState(() {
settings.Write();
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Mods have been scanned and updated.")));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Mod scanning complete")));
},
),
ListTile(
title: Text("Configure AutoRestart"),
leading: Icon(Icons.timer),
onTap: () async {
if (downloading) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Wait until the download completes")));
return;
}
var reply = await Navigator.pushNamed(
context, "/server/autorestart",
arguments: settings.inst!.timer);