import 'dart:async'; import 'dart:io'; import 'package:servermanager/game.dart'; import 'package:servermanager/pathtools.dart'; import 'package:servermanager/proton.dart'; import 'package:servermanager/settings.dart'; import 'package:mc_rcon_dart/mc_rcon_dart.dart'; enum States { Idle, // For when the state machine is waiting for a state change Starting, // For when the server is starting up ModUpdateCheck, // For when the mods are being checked in the jail folder against the live mods WarnPlayersNonIntrusive, // Gives a non-instrusive warning about the upcoming restart WarnPlayersIntrusive, // Sends a message intrusively about the upcoming restart FullStop, // Intends to set the inactive state, and immediately stops the server Inactive // The inactive state will be used for when the state machine is not supposed to be doing anything. } class StateMachine { var _currentState = States.Inactive; StreamController _stateController = StreamController.broadcast(); Stream get stateChanges => _stateController.stream; States get currentState => _currentState; void changeState(States n) { _currentState = n; _stateController.add(n); } Future runTask() async { if (currentState == States.Idle) { return; // Nothing to do here } else if (currentState == States.FullStop) { Settings settings = Settings(); await createSocket("127.0.0.1", port: settings.inst!.serverSettings.RconPort); login(settings.inst!.serverSettings.RconPassword); sendCommand("shutdown"); changeState(States.Inactive); } else if (currentState == States.Starting) { // Server startup in progress Settings settings = Settings(); await settings.RunUpdate(valid: false); await doDownloadMods(settings.getModPath()); settings.inst!.mods = await doScanMods(settings.getModPath()); await settings.writeOutModListFile(); var conanArgs = [ "-RconEnabled=1", "-RconPassword=${settings.inst!.serverSettings.RconPassword}", "-RconPort=${settings.inst!.serverSettings.RconPort}", "-Port=${settings.inst!.serverSettings.GamePort}", "-QueryPort=${settings.inst!.serverSettings.QueryPort}", "-log" ]; // Start the server now if (Platform.isWindows) { Process.start( PathHelper.combine( settings.getServerPath(), "ConanSandboxServer.exe"), conanArgs, workingDirectory: settings.getServerPath()); } else { runDetachedProton( PathHelper.combine( settings.getServerPath(), "ConanSandboxServer.exe"), conanArgs, settings.getServerPath()); } changeState(States.Idle); } } StateMachine() { stateChanges.listen((event) async { await runTask(); }); } }