import 'dart:io'; import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:servermanager/mod.dart'; import 'package:servermanager/settings.dart'; class GameServerPage extends StatefulWidget { Settings settings; GameServerPage({super.key, required this.settings}); @override GameServerPageState createState() => GameServerPageState(settings: settings); } class GameServerPageState extends State { Settings settings; GameServerPageState({required this.settings}); var downloading = false; late Stream> download_stream; TextEditingController ValueControl = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Conan Exiles Server Manager - Game Server"), backgroundColor: Color.fromARGB(255, 100, 0, 0), ), body: WillPopScope( onWillPop: () async { if (downloading) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Wait until the download completes"))); return false; } else return true; }, child: SingleChildScrollView( padding: EdgeInsets.all(16), child: Column( children: [ ListTile( title: settings.serverInstalled() ? Text("Update / Validate Server Install") : Text("Initial Server Download"), subtitle: settings.serverInstalled() ? Text( "Validates game files or performs an update. This is done when starting the server as well.") : Text( "Download the game server. This is step 1, after having downloaded steamcmd."), leading: Icon(Icons.numbers), onTap: () async { if (downloading) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("Wait until the download completes"))); return; } if (!settings.isValid()) return; Directory(settings.getServerPath()).createSync(); setState(() { downloading = true; }); // Start server download into folder await settings.RunUpdate(); setState(() { downloading = false; }); }, ), if (downloading) ListTile( title: Text("Downloading..."), leading: Icon(Icons.downloading), ), ListTile( title: Text("Mods"), leading: Icon(Icons.build), subtitle: Text("Server Mod Management"), onTap: () { if (downloading) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("Wait until the download completes"))); return; } Navigator.pushNamed(context, "/server/mods"); }, ), ListTile( title: Text("Status:"), subtitle: Text("Not Running"), leading: Icon(Icons.error), ) ], )), ), ); } } class ModManager extends StatefulWidget { Settings settings; ModManager({super.key, required this.settings}); @override ModManagerState createState() => ModManagerState(settings: settings); } class ModManagerState extends State { Settings settings; ModManagerState({required this.settings}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Conan Exiles Server Manager - Mod Manager"), backgroundColor: Color.fromARGB(255, 100, 0, 0), ), body: WillPopScope( child: ReorderableListView.builder( onReorder: (oldIndex, newIndex) { if (oldIndex < newIndex) { // From top to Bottom int end = newIndex - 1; Mod item = settings.mods[oldIndex]; int i = 0; int local = oldIndex; do { settings.mods[local] = settings.mods[++local]; i++; } while (i < end - oldIndex); settings.mods[end] = item; } else if (oldIndex > newIndex) { //From bottom to top Mod item = settings.mods[oldIndex]; for (int i = oldIndex; i > newIndex; i--) { settings.mods[i] = settings.mods[i - 1]; } settings.mods[newIndex] = item; } setState(() { settings.Write(); }); }, itemBuilder: (ctx, idx) { Mod mod = settings.mods[idx]; return Padding( key: Key("${mod.mod_instance_id}"), padding: EdgeInsets.all(12), child: ListTile( title: Text(mod.mod_name), subtitle: Text("ID: " + mod.mod_id.toString()), onTap: () async { final reply = await Navigator.pushNamed( context, "/server/mods/edit", arguments: Mod( mod_id: mod.mod_id, mod_name: mod.mod_name, newMod: false)); if (reply != null) setState(() { settings.mods[idx] = reply as Mod; }); else setState(() { settings.mods.removeAt(idx); }); }, ), ); }, itemCount: settings.mods.length, ), onWillPop: () async { Navigator.pop(context); return true; }, ), floatingActionButton: ElevatedButton( child: Icon(Icons.add), onPressed: () async { // Open new mod info screen final reply = await Navigator.pushNamed(context, "/server/mods/edit", arguments: Mod(newMod: true)); if (reply != null) { Mod mod = reply as Mod; setState(() { settings.mods.add(mod); settings.Write(); }); } }, ), ); } } class ModPage extends StatelessWidget { bool initDone = false; TextEditingController id = TextEditingController(); TextEditingController name = TextEditingController(); String instance = ""; bool isNewMod = false; bool willDelete = false; @override Widget build(BuildContext context) { final args = ModalRoute.of(context)!.settings.arguments as Mod?; if (!initDone) { initDone = true; if (args != null) { id.text = args.mod_id.toString(); name.text = args.mod_name; isNewMod = args.newMod; instance = args.mod_instance_id; } } return Scaffold( appBar: AppBar( title: Text("Mod Editor"), backgroundColor: Color.fromARGB(255, 100, 0, 0), ), body: WillPopScope( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column(children: [ Row( children: [ SizedBox( width: 150, child: ListTile( leading: Icon(Icons.abc_rounded), title: Text("Mod Name"), )), Expanded( child: TextField( controller: name, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(4)))), ) ], ), SizedBox( height: 16, ), Row( children: [ SizedBox( width: 150, child: ListTile( leading: Icon(Icons.perm_identity), title: Text("Mod ID")), ), Expanded( child: TextField( controller: id, keyboardType: TextInputType.number, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(4))), )) ], ), SizedBox( height: 16, ), ListTile( title: Text("Mod Instance ID"), subtitle: Text(instance), ), if (!isNewMod) ElevatedButton( onPressed: () { willDelete = true; Navigator.pop(context); }, child: Row( children: [ Icon(Icons.delete), SizedBox( width: 4, ), Text("Remove Mod") ], )) ]), ), onWillPop: () async { int id_val = 0; try { id_val = int.parse(id.text); } catch (E) {} if (willDelete) Navigator.pop(context, null); else Navigator.pop(context, Mod(mod_id: id_val, mod_name: name.text, newMod: false)); return true; }, ), ); } }