From 8162dbe97ae58543b8e2597b8ff0793202100b1e Mon Sep 17 00:00:00 2001 From: zontreck Date: Sat, 4 Nov 2023 16:55:13 -0700 Subject: [PATCH] Move code for downloading mods into a more universal function --- lib/game.dart | 175 +++++++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 82 deletions(-) diff --git a/lib/game.dart b/lib/game.dart index 06e156b..9dbd360 100644 --- a/lib/game.dart +++ b/lib/game.dart @@ -7,6 +7,87 @@ import 'package:servermanager/mod.dart'; import 'package:servermanager/pathtools.dart'; import 'package:servermanager/settings.dart'; +Future 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 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> doScanMods(String modsFolder) async { + Settings settings = Settings(); + + List 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 { 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 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 { 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 - setState(() { - settings.inst!.mods[index] = Mod( - mod_hash: hash, - mod_id: M.mod_id, - mod_pak: name, - mod_name: M.mod_name); - }); - } - } - } - + var mods = await doScanMods(settings.getModPath()); setState(() { + settings.inst!.mods = mods; + 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);