ConanServerManager/lib/game.dart
2023-11-01 03:28:33 -07:00

316 lines
9.8 KiB
Dart

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<GameServerPage> {
Settings settings;
GameServerPageState({required this.settings});
var downloading = false;
late Stream<List<int>> 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<ModManager> {
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;
},
),
);
}
}