Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a9c9a0de68 |
@@ -1,167 +1,114 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using NLog;
|
|
||||||
using Torch.API;
|
using Torch.API;
|
||||||
using Torch.Views;
|
using Torch.Views;
|
||||||
|
|
||||||
namespace Torch.Server
|
namespace Torch.Server;
|
||||||
{
|
|
||||||
// TODO: redesign this gerbage
|
|
||||||
public class TorchConfig : CommandLine, ITorchConfig, INotifyPropertyChanged
|
|
||||||
{
|
|
||||||
private static Logger _log = LogManager.GetLogger("Config");
|
|
||||||
|
|
||||||
|
public class TorchConfig : ViewModel, ITorchConfig
|
||||||
|
{
|
||||||
public bool ShouldUpdatePlugins => (GetPluginUpdates && !NoUpdate) || ForceUpdate;
|
public bool ShouldUpdatePlugins => (GetPluginUpdates && !NoUpdate) || ForceUpdate;
|
||||||
public bool ShouldUpdateTorch => (GetTorchUpdates && !NoUpdate) || ForceUpdate;
|
public bool ShouldUpdateTorch => (GetTorchUpdates && !NoUpdate) || ForceUpdate;
|
||||||
|
|
||||||
private bool _autostart;
|
|
||||||
private bool _restartOnCrash;
|
|
||||||
private bool _noGui;
|
|
||||||
private bool _getPluginUpdates = true;
|
|
||||||
private bool _getTorchUpdates = true;
|
|
||||||
private int _tickTimeout = 60;
|
|
||||||
private bool _localPlugins;
|
|
||||||
private bool _disconnectOnRestart;
|
|
||||||
private string _chatName = "Server";
|
|
||||||
private string _chatColor = "Red";
|
|
||||||
private bool _enableWhitelist = false;
|
|
||||||
private List<ulong> _whitelist = new List<ulong>();
|
|
||||||
private int _windowWidth = 980;
|
|
||||||
private int _windowHeight = 588;
|
|
||||||
private bool _independentConsole = false;
|
|
||||||
private bool _enableAsserts = false;
|
|
||||||
private int _fontSize = 16;
|
|
||||||
private UGCServiceType _ugcServiceType = UGCServiceType.Steam;
|
|
||||||
private bool _entityManagerEnabled = true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[XmlIgnore, Arg("noupdate", "Disable automatically downloading game and plugin updates.")]
|
[XmlIgnore]
|
||||||
public bool NoUpdate { get; set; }
|
public bool NoUpdate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[XmlIgnore, Arg("forceupdate", "Manually check for and install updates.")]
|
[XmlIgnore]
|
||||||
public bool ForceUpdate { get; set; }
|
public bool ForceUpdate { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Permanent flag to ALWAYS automatically start the server
|
/// Permanent flag to ALWAYS automatically start the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Display(Name = "Auto Start", Description = "Permanent flag to ALWAYS automatically start the server.", GroupName = "Server")]
|
[Display(Name = "Auto Start", Description = "Permanent flag to ALWAYS automatically start the server.", GroupName = "Server")]
|
||||||
public bool Autostart { get => _autostart; set => Set(value, ref _autostart); }
|
public bool Autostart { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Temporary flag to automatically start the server only on the next run
|
/// Temporary flag to automatically start the server only on the next run
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Arg("autostart", "Start the server immediately.")]
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
public bool TempAutostart { get; set; }
|
public bool TempAutostart { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Arg("restartoncrash", "Automatically restart the server if it crashes.")]
|
|
||||||
[Display(Name = "Restart On Crash", Description = "Automatically restart the server if it crashes.", GroupName = "Server")]
|
[Display(Name = "Restart On Crash", Description = "Automatically restart the server if it crashes.", GroupName = "Server")]
|
||||||
public bool RestartOnCrash { get => _restartOnCrash; set => Set(value, ref _restartOnCrash); }
|
public bool RestartOnCrash { get; set; }
|
||||||
|
|
||||||
public string InstancePath { get; set; }
|
public string InstancePath { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Arg("nogui", "Do not show the Torch UI.")]
|
|
||||||
[Display(Name = "No GUI", Description = "Do not show the Torch UI.", GroupName = "Window")]
|
[Display(Name = "No GUI", Description = "Do not show the Torch UI.", GroupName = "Window")]
|
||||||
public bool NoGui { get => _noGui; set => Set(value, ref _noGui); }
|
public bool NoGui { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Display(Name = "Update Torch", Description = "Check every start for new versions of torch.", GroupName = "Server")]
|
[Display(Name = "Update Torch", Description = "Check every start for new versions of torch.",
|
||||||
public bool GetTorchUpdates { get => _getTorchUpdates; set => Set(value, ref _getTorchUpdates); }
|
GroupName = "Server")]
|
||||||
|
public bool GetTorchUpdates { get; set; } = true;
|
||||||
|
|
||||||
public string InstanceName { get; set; }
|
public string InstanceName { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Display(Name = "Update Plugins", Description = "Check every start for new versions of plugins.", GroupName = "Server")]
|
[Display(Name = "Update Plugins", Description = "Check every start for new versions of plugins.",
|
||||||
public bool GetPluginUpdates { get => _getPluginUpdates; set => Set(value, ref _getPluginUpdates); }
|
GroupName = "Server")]
|
||||||
|
public bool GetPluginUpdates { get; set; } = true;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Display(Name = "Watchdog Timeout", Description = "Watchdog timeout (in seconds).", GroupName = "Server")]
|
[Display(Name = "Watchdog Timeout", Description = "Watchdog timeout (in seconds).", GroupName = "Server")]
|
||||||
public int TickTimeout { get => _tickTimeout; set => Set(value, ref _tickTimeout); }
|
public int TickTimeout { get; set; } = 60;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Arg("plugins", "Starts Torch with the given plugin GUIDs (space delimited).")]
|
public List<Guid> Plugins { get; set; } = new();
|
||||||
public List<Guid> Plugins { get; set; } = new List<Guid>();
|
|
||||||
|
|
||||||
[Arg("localplugins", "Loads all pluhins from disk, ignores the plugins defined in config.")]
|
|
||||||
[Display(Name = "Local Plugins", Description = "Loads all pluhins from disk, ignores the plugins defined in config.", GroupName = "In-Game")]
|
[Display(Name = "Local Plugins", Description = "Loads all pluhins from disk, ignores the plugins defined in config.", GroupName = "In-Game")]
|
||||||
public bool LocalPlugins { get => _localPlugins; set => Set(value, ref _localPlugins); }
|
public bool LocalPlugins { get; set; }
|
||||||
|
|
||||||
[Arg("disconnect", "When server restarts, all clients are rejected to main menu to prevent auto rejoin.")]
|
|
||||||
[Display(Name = "Auto Disconnect", Description = "When server restarts, all clients are rejected to main menu to prevent auto rejoin.", GroupName = "In-Game")]
|
[Display(Name = "Auto Disconnect", Description = "When server restarts, all clients are rejected to main menu to prevent auto rejoin.", GroupName = "In-Game")]
|
||||||
public bool DisconnectOnRestart { get => _disconnectOnRestart; set => Set(value, ref _disconnectOnRestart); }
|
public bool DisconnectOnRestart { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Chat Name", Description = "Default name for chat from gui, broadcasts etc..", GroupName = "In-Game")]
|
[Display(Name = "Chat Name", Description = "Default name for chat from gui, broadcasts etc..",
|
||||||
public string ChatName { get => _chatName; set => Set(value, ref _chatName); }
|
GroupName = "In-Game")]
|
||||||
|
public string ChatName { get; set; } = "Server";
|
||||||
|
|
||||||
[Display(Name = "Chat Color", Description = "Default color for chat from gui, broadcasts etc.. (Red, Blue, White, Green)", GroupName = "In-Game")]
|
[Display(Name = "Chat Color",
|
||||||
public string ChatColor { get => _chatColor; set => Set(value, ref _chatColor); }
|
Description = "Default color for chat from gui, broadcasts etc.. (Red, Blue, White, Green)",
|
||||||
|
GroupName = "In-Game")]
|
||||||
|
public string ChatColor { get; set; } = "Red";
|
||||||
|
|
||||||
[Display(Name = "Enable Whitelist", Description = "Enable Whitelist to prevent random players join while maintance, tests or other.", GroupName = "In-Game")]
|
[Display(Name = "Enable Whitelist", Description = "Enable Whitelist to prevent random players join while maintance, tests or other.", GroupName = "In-Game")]
|
||||||
public bool EnableWhitelist { get => _enableWhitelist; set => Set(value, ref _enableWhitelist); }
|
public bool EnableWhitelist { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Whitelist", Description = "Collection of whitelisted steam ids.", GroupName = "In-Game")]
|
[Display(Name = "Whitelist", Description = "Collection of whitelisted steam ids.", GroupName = "In-Game")]
|
||||||
public List<ulong> Whitelist { get => _whitelist; set => Set(value, ref _whitelist); }
|
public List<ulong> Whitelist { get; set; } = new();
|
||||||
|
|
||||||
[Display(Name = "Width", Description = "Default window width.", GroupName = "Window")]
|
[Display(Name = "Width", Description = "Default window width.", GroupName = "Window")]
|
||||||
public int WindowWidth { get => _windowWidth; set => Set(value, ref _windowWidth); }
|
public int WindowWidth { get; set; } = 980;
|
||||||
|
|
||||||
[Display(Name = "Height", Description = "Default window height", GroupName = "Window")]
|
[Display(Name = "Height", Description = "Default window height", GroupName = "Window")]
|
||||||
public int WindowHeight { get => _windowHeight; set => Set(value, ref _windowHeight); }
|
public int WindowHeight { get; set; } = 588;
|
||||||
|
|
||||||
[Display(Name = "Font Size", Description = "Font size for logging text box. (default is 16)", GroupName = "Window")]
|
[Display(Name = "Font Size", Description = "Font size for logging text box. (default is 16)",
|
||||||
public int FontSize { get => _fontSize; set => Set(value, ref _fontSize); }
|
GroupName = "Window")]
|
||||||
|
public int FontSize { get; set; } = 16;
|
||||||
|
|
||||||
[Display(Name = "UGC Service Type", Description = "Service for downloading mods", GroupName = "Server")]
|
[Display(Name = "UGC Service Type", Description = "Service for downloading mods", GroupName = "Server")]
|
||||||
public UGCServiceType UgcServiceType
|
public UGCServiceType UgcServiceType { get; set; } = UGCServiceType.Steam;
|
||||||
{
|
|
||||||
get => _ugcServiceType;
|
|
||||||
set => Set(value, ref _ugcServiceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LastUsedTheme { get; set; } = "Torch Theme";
|
public string LastUsedTheme { get; set; } = "Torch Theme";
|
||||||
|
|
||||||
//Prevent reserved players being written to disk, but allow it to be read
|
|
||||||
//remove this when ReservedPlayers is removed
|
|
||||||
private bool ShouldSerializeReservedPlayers() => false;
|
|
||||||
|
|
||||||
[Arg("console", "Keeps a separate console window open after the main UI loads.")]
|
|
||||||
[Display(Name = "Independent Console", Description = "Keeps a separate console window open after the main UI loads.", GroupName = "Window")]
|
[Display(Name = "Independent Console", Description = "Keeps a separate console window open after the main UI loads.", GroupName = "Window")]
|
||||||
public bool IndependentConsole { get => _independentConsole; set => Set(value, ref _independentConsole); }
|
public bool IndependentConsole { get; set; }
|
||||||
|
|
||||||
[XmlIgnore]
|
[XmlIgnore]
|
||||||
[Arg("testplugin", "Path to a plugin to debug. For development use only.")]
|
|
||||||
public string TestPlugin { get; set; }
|
public string TestPlugin { get; set; }
|
||||||
|
|
||||||
[Arg("asserts", "Enable Keen's assert logging.")]
|
|
||||||
[Display(Name = "Enable Asserts", Description = "Enable Keen's assert logging.", GroupName = "Server")]
|
[Display(Name = "Enable Asserts", Description = "Enable Keen's assert logging.", GroupName = "Server")]
|
||||||
public bool EnableAsserts { get => _enableAsserts; set => Set(value, ref _enableAsserts); }
|
public bool EnableAsserts { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Enable Entity Manager", Description = "Enable Entity Manager tab. (can affect performance)",
|
[Display(Name = "Enable Entity Manager", Description = "Enable Entity Manager tab. (can affect performance)",
|
||||||
GroupName = "Server")]
|
GroupName = "Server")]
|
||||||
public bool EntityManagerEnabled
|
public bool EntityManagerEnabled { get; set; } = true;
|
||||||
{
|
|
||||||
get => _entityManagerEnabled;
|
|
||||||
set => Set(value, ref _entityManagerEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
public TorchConfig() { }
|
|
||||||
|
|
||||||
protected void Set<T>(T value, ref T field, [CallerMemberName] string callerName = default)
|
|
||||||
{
|
|
||||||
field = value;
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(callerName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// for backward compatibility
|
// for backward compatibility
|
||||||
public void Save(string path = null) => Initializer.Instance?.ConfigPersistent?.Save(path);
|
public void Save(string path = null) => Initializer.Instance?.ConfigPersistent?.Save(path);
|
||||||
}
|
|
||||||
}
|
}
|
@@ -205,16 +205,30 @@ namespace Torch.Server
|
|||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
StopInternal();
|
StopInternal();
|
||||||
var config = (TorchConfig)Config;
|
|
||||||
LogManager.Flush();
|
LogManager.Flush();
|
||||||
|
|
||||||
string exe = Assembly.GetExecutingAssembly().Location.Replace("dll", "exe");
|
#if DEBUG
|
||||||
|
|
||||||
config.TempAutostart = true;
|
|
||||||
|
|
||||||
Process.Start(exe, $"-waitForPid {Environment.ProcessId} {config}");
|
|
||||||
|
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var exe = Assembly.GetExecutingAssembly().Location.Replace("dll", "exe");
|
||||||
|
|
||||||
|
var args = Environment.GetCommandLineArgs();
|
||||||
|
|
||||||
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
if (args[i].Contains(' '))
|
||||||
|
args[i] = $"\"{args[i]}\"";
|
||||||
|
|
||||||
|
if (!args[i].Contains("--tempAutostart", StringComparison.InvariantCultureIgnoreCase) &&
|
||||||
|
!args[i].Contains("--waitForPid", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
args[i] = string.Empty;
|
||||||
|
args[++i] = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Process.Start(exe, $"--waitForPid {Environment.ProcessId} --tempAutostart true {string.Join(" ", args)}");
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
Name = "Restart thread"
|
Name = "Restart thread"
|
||||||
|
@@ -1,138 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using NLog;
|
|
||||||
|
|
||||||
namespace Torch
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Base class that adds tools for setting type properties through the command line.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class CommandLine
|
|
||||||
{
|
|
||||||
private readonly string _argPrefix;
|
|
||||||
private readonly Dictionary<ArgAttribute, PropertyInfo> _args = new Dictionary<ArgAttribute, PropertyInfo>();
|
|
||||||
private readonly Logger _log = LogManager.GetCurrentClassLogger();
|
|
||||||
|
|
||||||
protected CommandLine(string argPrefix = "-")
|
|
||||||
{
|
|
||||||
_argPrefix = argPrefix;
|
|
||||||
foreach (var prop in GetType().GetProperties())
|
|
||||||
{
|
|
||||||
var attr = prop.GetCustomAttribute<ArgAttribute>();
|
|
||||||
if (attr == null)
|
|
||||||
continue;
|
|
||||||
_args.Add(attr, prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetHelp()
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
foreach (var property in _args)
|
|
||||||
{
|
|
||||||
var attr = property.Key;
|
|
||||||
sb.AppendLine($"{_argPrefix}{attr.Name.PadRight(24)}{attr.Description}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
var args = new List<string>();
|
|
||||||
foreach (var prop in _args)
|
|
||||||
{
|
|
||||||
var attr = prop.Key;
|
|
||||||
if (prop.Value.PropertyType == typeof(bool) && (bool)prop.Value.GetValue(this))
|
|
||||||
{
|
|
||||||
args.Add($"{_argPrefix}{attr.Name}");
|
|
||||||
}
|
|
||||||
else if (prop.Value.PropertyType == typeof(string))
|
|
||||||
{
|
|
||||||
var str = (string)prop.Value.GetValue(this);
|
|
||||||
if (string.IsNullOrEmpty(str))
|
|
||||||
continue;
|
|
||||||
args.Add($"{_argPrefix}{attr.Name} \"{str}\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Join(" ", args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Parse(string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (args[0] == $"{_argPrefix}help")
|
|
||||||
{
|
|
||||||
Console.WriteLine(GetHelp());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < args.Length; i++)
|
|
||||||
{
|
|
||||||
if (!args[i].StartsWith(_argPrefix))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (var property in _args)
|
|
||||||
{
|
|
||||||
var argName = property.Key.Name;
|
|
||||||
if (argName == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (string.Compare(argName, 0, args[i], 1, argName.Length, StringComparison.InvariantCultureIgnoreCase) == 0)
|
|
||||||
{
|
|
||||||
if (property.Value.PropertyType == typeof(bool))
|
|
||||||
property.Value.SetValue(this, true);
|
|
||||||
|
|
||||||
if (property.Value.PropertyType == typeof(string))
|
|
||||||
property.Value.SetValue(this, args[++i]);
|
|
||||||
|
|
||||||
if (property.Value.PropertyType == typeof(List<Guid>))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
var l = new List<Guid>(16);
|
|
||||||
while (i < args.Length && !args[i].StartsWith(_argPrefix))
|
|
||||||
{
|
|
||||||
if (Guid.TryParse(args[i], out Guid g))
|
|
||||||
{
|
|
||||||
l.Add(g);
|
|
||||||
_log.Info($"added plugin {g}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_log.Warn($"Failed to parse GUID {args[i]}");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
property.Value.SetValue(this, l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Error parsing arg {argName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ArgAttribute : Attribute
|
|
||||||
{
|
|
||||||
public string Name { get; }
|
|
||||||
public string Description { get; }
|
|
||||||
public ArgAttribute(string name, string description)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Description = description;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user