Added and implemented a basic command-line parser.
This replaces the switch-case in HandleCommandLine and HandleCommandLinePostConfigLoad
This commit is contained in:
parent
047f9e7475
commit
fc7460c7d5
5 changed files with 600 additions and 202 deletions
306
TShockAPI/CLI/CommandLineParser.cs
Normal file
306
TShockAPI/CLI/CommandLineParser.cs
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace TShockAPI.CLI
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple command-line parser for retrieving basic information from a command-line. Array types are not supported
|
||||
/// </summary>
|
||||
public class CommandLineParser
|
||||
{
|
||||
private List<FlagSet> _flags = new List<FlagSet>();
|
||||
private Dictionary<FlagSet, object> _results = new Dictionary<FlagSet, object>();
|
||||
private string[] _source;
|
||||
|
||||
/// <summary>
|
||||
/// Resets the CommandLineParser, removing any results and flags, and clearing the source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser Reset()
|
||||
{
|
||||
_flags.Clear();
|
||||
_results.Clear();
|
||||
_source = null;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a flag to be parsed
|
||||
/// </summary>
|
||||
/// <param name="flag">The flag to be added</param>
|
||||
/// <param name="noArgs">Whether or not the flag is followed by an argument</param>
|
||||
public CommandLineParser AddFlag(string flag, bool noArgs = false)
|
||||
{
|
||||
FlagSet flags = new FlagSet(flag) { NoArgs = noArgs };
|
||||
return AddFlags(flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a flag to be parsed, with the given callback being invoked with the flag's argument when it is found.
|
||||
/// The callback's parameter is the argument passed to the flag
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
/// <param name="callback"></param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser AddFlag(string flag, Action<string> callback)
|
||||
{
|
||||
FlagSet flags = new FlagSet(flag) { callback = callback };
|
||||
return AddFlags(flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a flag to be parsed, with the given callback being invoked when the flag is found.
|
||||
/// This method assumes the flag has no arguments
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
/// <param name="callback"></param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser AddFlag(string flag, Action callback)
|
||||
{
|
||||
FlagSet flags = new FlagSet(flag) { NoArgs = true, callback = callback };
|
||||
return AddFlags(flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a range of flags to be parsed
|
||||
/// </summary>
|
||||
/// <param name="flags">The FlagSet to be added</param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser AddFlags(FlagSet flags)
|
||||
{
|
||||
if (_flags.Contains(flags))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
_flags.Add(flags);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a range of flags to be parsed, with the given callback being invoked with the flag's argument when it is found.
|
||||
/// The callback's parameter is the argument passed to the flag
|
||||
/// </summary>
|
||||
/// <param name="flags">The FlagSet to be added</param>
|
||||
/// <param name="callback">An Action with a single string parameter. This parameter is the value passed to the flag</param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser AddFlags(FlagSet flags, Action<string> callback)
|
||||
{
|
||||
flags.callback = callback;
|
||||
return AddFlags(flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a range of flags to be parsed, with the given callback being invoked when the flag's argument is found.
|
||||
/// This method assumes the flag has no arguments
|
||||
/// </summary>
|
||||
/// <param name="flags">The FlagSet to be added</param>
|
||||
/// <param name="callback">An Action with no parameters.</param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser AddFlags(FlagSet flags, Action callback)
|
||||
{
|
||||
flags.callback = callback;
|
||||
flags.NoArgs = true;
|
||||
return AddFlags(flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a callback after a flag's parsing has been completed.
|
||||
/// This method automatically attaches the callback to the last added flag
|
||||
/// </summary>
|
||||
/// <param name="callback">An Action with no parameters.</param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser After(Action callback)
|
||||
{
|
||||
FlagSet flags = _flags.Last();
|
||||
flags.continuation = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the result of a FlagSet, cast to the given type parameter. Array types are not supported
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="flags"></param>
|
||||
/// <returns></returns>
|
||||
public T Get<T>(FlagSet flags)
|
||||
{
|
||||
if (!_results.ContainsKey(flags))
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
object result = _results[flags];
|
||||
Type t = typeof(T);
|
||||
|
||||
if (t == typeof(string))
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
return (T)(object)string.Empty;
|
||||
}
|
||||
|
||||
return (T)result;
|
||||
}
|
||||
|
||||
if (t.IsValueType)
|
||||
{
|
||||
TypeConverter tc = TypeDescriptor.GetConverter(t);
|
||||
return (T)tc.ConvertFromString(result.ToString());
|
||||
}
|
||||
|
||||
return (T)Activator.CreateInstance(t, result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the given source for flags registered with the parser
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public CommandLineParser ParseFromSource(string[] source)
|
||||
{
|
||||
_source = source;
|
||||
|
||||
for (int i = 0; i < source.Length - 1; i++)
|
||||
{
|
||||
string flag = source[i].ToLowerInvariant();
|
||||
string argument = source[i + 1];
|
||||
|
||||
FlagSet flags = _flags.FirstOrDefault(f => f.Contains(flag));
|
||||
if (flags == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags.NoArgs)
|
||||
{
|
||||
if (flags.callback != null)
|
||||
{
|
||||
((Action)flags.callback).Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
_results.Add(flags, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags.callback != null)
|
||||
{
|
||||
((Action<string>)flags.callback).Invoke(argument);
|
||||
}
|
||||
else
|
||||
{
|
||||
_results.Add(flags, argument);
|
||||
}
|
||||
}
|
||||
flags.continuation?.Invoke();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the result of a flag, cast to the given type parameter. Array types are not supported
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="flag"></param>
|
||||
/// <returns></returns>
|
||||
public T Get<T>(string flag)
|
||||
{
|
||||
FlagSet flags = _flags.FirstOrDefault(f => f.Contains(flag));
|
||||
if (flags == null)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
return Get<T>(flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the result of a flag, cast to the given type parameter. Array types are not supported
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="flag"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryGet<T>(string flag, out T value)
|
||||
{
|
||||
FlagSet flags = _flags.FirstOrDefault(f => f.Contains(flag));
|
||||
if (flags == null)
|
||||
{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryGet(flags, out value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the result of a FlagSet, cast to the given type parameter. Array types are not supported
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="flags"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryGet<T>(FlagSet flags, out T value)
|
||||
{
|
||||
object result = _results[flags];
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
//Null result shouldn't happen, but return false if it does
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
Type t = typeof(T);
|
||||
|
||||
//Strings get special handling because the result object is a string
|
||||
if (t == typeof(string))
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
//Null strings shouldn't happen, but return false if it does
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
value = (T)result;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Value types get converted with a TypeConverter
|
||||
if (t.IsValueType)
|
||||
{
|
||||
try
|
||||
{
|
||||
TypeConverter tc = TypeDescriptor.GetConverter(t);
|
||||
value = (T)tc.ConvertFrom(result);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//Reference types get created with an Activator
|
||||
value = (T)Activator.CreateInstance(t, result);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
TShockAPI/CLI/FlagSet.cs
Normal file
71
TShockAPI/CLI/FlagSet.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TShockAPI.CLI
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a set of flags that are responsible for one CL argument
|
||||
/// </summary>
|
||||
public class FlagSet : IEquatable<FlagSet>
|
||||
{
|
||||
private IEnumerable<string> _flags;
|
||||
|
||||
internal object callback;
|
||||
internal Action continuation;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the set of flags represented by this FlagSet is followed by an argument
|
||||
/// </summary>
|
||||
public bool NoArgs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="FlagSet"/> with the given flags
|
||||
/// </summary>
|
||||
/// <param name="flags">Flags represented by this FlagSet</param>
|
||||
public FlagSet(params string[] flags)
|
||||
{
|
||||
if (flags == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(flags));
|
||||
}
|
||||
|
||||
_flags = flags.Select(f => f.ToLowerInvariant());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="FlagSet"/> with the given flags and arguments option
|
||||
/// </summary>
|
||||
/// <param name="flags">Flags represented by this FlagSet</param>
|
||||
/// <param name="noArgs">Whether or not the flags specified will be followed by an argument</param>
|
||||
public FlagSet(string[] flags, bool noArgs) : this(flags)
|
||||
{
|
||||
NoArgs = noArgs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether or not this flag set contains the given flag
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
/// <returns></returns>
|
||||
public bool Contains(string flag)
|
||||
{
|
||||
return _flags.Contains(flag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether or not this flag set is equatable to another
|
||||
/// </summary>
|
||||
/// <param name="other"></param>
|
||||
/// <returns></returns>
|
||||
public bool Equals(FlagSet other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return other._flags == _flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ using TShockAPI.ServerSideCharacters;
|
|||
using Terraria.Utilities;
|
||||
using Microsoft.Xna.Framework;
|
||||
using TShockAPI.Sockets;
|
||||
using TShockAPI.CLI;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
|
|
@ -127,6 +128,10 @@ namespace TShockAPI
|
|||
/// <summary>instance - Static reference to the TerrariaPlugin instance.</summary>
|
||||
public static TerrariaPlugin instance;
|
||||
/// <summary>
|
||||
/// Static reference to a <see cref="CommandLineParser"/> used for simple command-line parsing
|
||||
/// </summary>
|
||||
public static CommandLineParser CliParser { get; } = new CommandLineParser();
|
||||
/// <summary>
|
||||
/// Used for implementing REST Tokens prior to the REST system starting up.
|
||||
/// </summary>
|
||||
public static Dictionary<string, SecureRest.TokenData> RESTStartupTokens = new Dictionary<string, SecureRest.TokenData>();
|
||||
|
|
@ -204,6 +209,7 @@ namespace TShockAPI
|
|||
|
||||
try
|
||||
{
|
||||
CliParser.Reset();
|
||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||
|
||||
if (!Directory.Exists(SavePath))
|
||||
|
|
@ -295,6 +301,7 @@ namespace TShockAPI
|
|||
File.WriteAllText(Path.Combine(SavePath, "tshock.pid"),
|
||||
Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
CliParser.Reset();
|
||||
HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
|
||||
|
||||
Backups = new BackupManager(Path.Combine(SavePath, "backups"));
|
||||
|
|
@ -609,217 +616,202 @@ namespace TShockAPI
|
|||
/// <param name="parms">parms - The array of arguments passed in through the command line.</param>
|
||||
private void HandleCommandLine(string[] parms)
|
||||
{
|
||||
string path;
|
||||
for (int i = 0; i < parms.Length; i++)
|
||||
string path = null;
|
||||
|
||||
//Generic method for doing a path sanity check
|
||||
Action<string> pathChecker = (p) =>
|
||||
{
|
||||
switch (parms[i].ToLower())
|
||||
if (!string.IsNullOrWhiteSpace(p) && p.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
case "-configpath":
|
||||
{
|
||||
path = parms[++i];
|
||||
if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
SavePath = path;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Config path has been set to " + path, TraceLevel.Info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "-worldpath":
|
||||
{
|
||||
path = parms[++i];
|
||||
if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
Main.WorldPath = path;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "World path has been set to " + path, TraceLevel.Info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "-logpath":
|
||||
{
|
||||
path = parms[++i];
|
||||
if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
LogPath = path;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Log path has been set to " + path, TraceLevel.Info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "-logformat":
|
||||
{
|
||||
LogFormat = parms[++i];
|
||||
break;
|
||||
}
|
||||
case "-logclear":
|
||||
{
|
||||
bool.TryParse(parms[++i], out LogClear);
|
||||
break;
|
||||
}
|
||||
case "-dump":
|
||||
{
|
||||
Utils.PrepareLangForDump();
|
||||
Lang.setLang(true);
|
||||
ConfigFile.DumpDescriptions();
|
||||
Permissions.DumpDescriptions();
|
||||
ServerSideConfig.DumpDescriptions();
|
||||
RestManager.DumpDescriptions();
|
||||
Utils.DumpBuffs("BuffList.txt");
|
||||
Utils.DumpItems("Items-1_0.txt", -48, 235);
|
||||
Utils.DumpItems("Items-1_1.txt", 235, 604);
|
||||
Utils.DumpItems("Items-1_2.txt", 604, 2749);
|
||||
Utils.DumpItems("Items-1_3.txt", 2749, Main.maxItemTypes);
|
||||
Utils.DumpNPCs("NPCs.txt");
|
||||
Utils.DumpProjectiles("Projectiles.txt");
|
||||
Utils.DumpPrefixes("Prefixes.txt");
|
||||
Environment.Exit(1);
|
||||
break;
|
||||
}
|
||||
case "-config":
|
||||
{
|
||||
string filePath = parms[++i];
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Loading dedicated config file: {0}", filePath), TraceLevel.Verbose);
|
||||
Main.instance.LoadDedConfig(filePath);
|
||||
break;
|
||||
}
|
||||
case "-port":
|
||||
{
|
||||
int serverPort;
|
||||
if (int.TryParse(parms[++i], out serverPort))
|
||||
{
|
||||
Netplay.ListenPort = serverPort;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Listening on port {0}.", serverPort), TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The server should not start up if this argument is invalid.
|
||||
throw new InvalidOperationException("Invalid value given for command line argument \"-ip\".");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "-worldname":
|
||||
{
|
||||
string worldName = parms[++i];
|
||||
Main.instance.SetWorldName(worldName);
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("World name will be overridden by: {0}", worldName), TraceLevel.Verbose);
|
||||
|
||||
break;
|
||||
}
|
||||
case "-autoshutdown":
|
||||
{
|
||||
Main.instance.EnableAutoShutdown();
|
||||
break;
|
||||
}
|
||||
case "-autocreate":
|
||||
{
|
||||
string newOpt = parms[++i];
|
||||
Main.instance.autoCreate(newOpt);
|
||||
break;
|
||||
}
|
||||
case "-ip":
|
||||
{
|
||||
IPAddress ip;
|
||||
if (IPAddress.TryParse(parms[++i], out ip))
|
||||
{
|
||||
Netplay.ServerIP = ip;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Listening on IP {0}.", ip), TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The server should not start up if this argument is invalid.
|
||||
throw new InvalidOperationException("Invalid value given for command line argument \"-ip\".");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "-connperip":
|
||||
{
|
||||
int limit;
|
||||
if (int.TryParse(parms[++i], out limit))
|
||||
{
|
||||
/* Todo - Requires an OTAPI modification
|
||||
Netplay.MaxConnections = limit;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format(
|
||||
"Connections per IP have been limited to {0} connections.", limit), TraceLevel.Verbose);*/
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "\"-connperip\" is not supported in this version of TShock.", TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Invalid value given for command line argument \"-connperip\".", TraceLevel.Warning);
|
||||
|
||||
break;
|
||||
}
|
||||
case "-killinactivesocket":
|
||||
{
|
||||
// Netplay.killInactive = true;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "The argument -killinactivesocket is no longer present in Terraria.", TraceLevel.Warning);
|
||||
break;
|
||||
}
|
||||
case "-lang":
|
||||
{
|
||||
int langIndex;
|
||||
if (int.TryParse(parms[++i], out langIndex))
|
||||
{
|
||||
Lang.lang = langIndex;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Language index set to {0}.", langIndex), TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Invalid value given for command line argument \"-lang\".", TraceLevel.Warning);
|
||||
|
||||
break;
|
||||
}
|
||||
case "--provider-token":
|
||||
{
|
||||
StatTracker.ProviderToken = parms[++i];
|
||||
break;
|
||||
}
|
||||
case "--stats-optout":
|
||||
{
|
||||
StatTracker.OptOut = true;
|
||||
break;
|
||||
}
|
||||
case "--no-restart":
|
||||
{
|
||||
TShock.NoRestart = true;
|
||||
break;
|
||||
}
|
||||
path = p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//Prepare the parser with all the flags available
|
||||
CliParser
|
||||
.AddFlag("-configpath", pathChecker)
|
||||
//The .After Action is run after the pathChecker Action
|
||||
.After(() =>
|
||||
{
|
||||
SavePath = path ?? "tshock";
|
||||
if (path != null)
|
||||
{
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Config path has been set to " + path, TraceLevel.Info);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-worldpath", pathChecker)
|
||||
.After(() =>
|
||||
{
|
||||
if (path != null)
|
||||
{
|
||||
Main.WorldPath = path;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "World path has been set to " + path, TraceLevel.Info);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-logpath", pathChecker)
|
||||
.After(() =>
|
||||
{
|
||||
if (path != null)
|
||||
{
|
||||
LogPath = path;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Log path has been set to " + path, TraceLevel.Info);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-logformat", (format) =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(format)) { LogFormat = format; }
|
||||
})
|
||||
|
||||
.AddFlag("-config", (cfg) =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(cfg))
|
||||
{
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Loading dedicated config file: {0}", cfg), TraceLevel.Verbose);
|
||||
Main.instance.LoadDedConfig(cfg);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-port", (p) =>
|
||||
{
|
||||
int port;
|
||||
if (int.TryParse(p, out port))
|
||||
{
|
||||
Netplay.ListenPort = port;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Listening on port {0}.", port), TraceLevel.Verbose);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-worldname", (world) =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(world))
|
||||
{
|
||||
Main.instance.SetWorldName(world);
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("World name will be overridden by: {0}", world), TraceLevel.Verbose);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-ip", (ip) =>
|
||||
{
|
||||
IPAddress addr;
|
||||
if (IPAddress.TryParse(ip, out addr))
|
||||
{
|
||||
Netplay.ServerIP = addr;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Listening on IP {0}.", addr), TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The server should not start up if this argument is invalid.
|
||||
throw new InvalidOperationException("Invalid value given for command line argument \"-ip\".");
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-lang", (l) =>
|
||||
{
|
||||
int lang;
|
||||
if (int.TryParse(l, out lang))
|
||||
{
|
||||
Lang.lang = lang;
|
||||
ServerApi.LogWriter.PluginWriteLine(this, string.Format("Language index set to {0}.", lang), TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Invalid value given for command line argument \"-lang\".", TraceLevel.Warning);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("-autocreate", (size) =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(size))
|
||||
{
|
||||
Main.instance.autoCreate(size);
|
||||
}
|
||||
})
|
||||
|
||||
.AddFlag("--provider-token", (token) => StatTracker.ProviderToken = token)
|
||||
|
||||
//Flags without arguments
|
||||
.AddFlag("-logclear", () => LogClear = true)
|
||||
.AddFlag("-autoshutdown", () => Main.instance.EnableAutoShutdown())
|
||||
.AddFlag("-dump", () => Utils.Dump())
|
||||
.AddFlag("--stats-optout", () => StatTracker.OptOut = true)
|
||||
.AddFlag("--no-restart", () => NoRestart = true);
|
||||
|
||||
CliParser.ParseFromSource(parms);
|
||||
|
||||
/*"-connperip": Todo - Requires an OTAPI modification
|
||||
{
|
||||
int limit;
|
||||
if (int.TryParse(parms[++i], out limit))
|
||||
{
|
||||
//Netplay.MaxConnections = limit;
|
||||
//ServerApi.LogWriter.PluginWriteLine(this, string.Format(
|
||||
// "Connections per IP have been limited to {0} connections.", limit), TraceLevel.Verbose);
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "\"-connperip\" is not supported in this version of TShock.", TraceLevel.Verbose);
|
||||
}
|
||||
else
|
||||
ServerApi.LogWriter.PluginWriteLine(this, "Invalid value given for command line argument \"-connperip\".", TraceLevel.Warning);
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>HandleCommandLinePostConfigLoad - Handles additional command line options after the config file is read.</summary>
|
||||
/// <param name="parms">parms - The array of arguments passed in through the command line.</param>
|
||||
public static void HandleCommandLinePostConfigLoad(string[] parms)
|
||||
{
|
||||
for (int i = 0; i < parms.Length; i++)
|
||||
{
|
||||
switch (parms[i].ToLower())
|
||||
{
|
||||
case "-port":
|
||||
int port = Convert.ToInt32(parms[++i]);
|
||||
Netplay.ListenPort = port;
|
||||
Config.ServerPort = port;
|
||||
OverridePort = true;
|
||||
Log.ConsoleInfo("Port overridden by startup argument. Set to " + port);
|
||||
break;
|
||||
case "-rest-token":
|
||||
string token = Convert.ToString(parms[++i]);
|
||||
FlagSet portSet = new FlagSet("-port");
|
||||
FlagSet playerSet = new FlagSet("-maxplayers", "-players");
|
||||
FlagSet restTokenSet = new FlagSet("--rest-token", "-rest-token");
|
||||
FlagSet restEnableSet = new FlagSet("--rest-enabled", "-rest-enabled");
|
||||
FlagSet restPortSet = new FlagSet("--rest-port", "-rest-port");
|
||||
|
||||
CliParser
|
||||
.AddFlags(portSet, (p) =>
|
||||
{
|
||||
int port;
|
||||
if (int.TryParse(p, out port))
|
||||
{
|
||||
Netplay.ListenPort = port;
|
||||
Config.ServerPort = port;
|
||||
OverridePort = true;
|
||||
Log.ConsoleInfo("Port overridden by startup argument. Set to " + port);
|
||||
}
|
||||
})
|
||||
.AddFlags(restTokenSet, (token) =>
|
||||
{
|
||||
RESTStartupTokens.Add(token, new SecureRest.TokenData { Username = "null", UserGroupName = "superadmin" });
|
||||
Console.WriteLine("Startup parameter overrode REST token.");
|
||||
break;
|
||||
case "-rest-enabled":
|
||||
Config.RestApiEnabled = Convert.ToBoolean(parms[++i]);
|
||||
Console.WriteLine("Startup parameter overrode REST enable.");
|
||||
break;
|
||||
case "-rest-port":
|
||||
Config.RestApiPort = Convert.ToInt32(parms[++i]);
|
||||
})
|
||||
.AddFlags(restEnableSet, (e) =>
|
||||
{
|
||||
bool enabled;
|
||||
if (bool.TryParse(e, out enabled))
|
||||
{
|
||||
Config.RestApiEnabled = enabled;
|
||||
Console.WriteLine("Startup parameter overrode REST enable.");
|
||||
}
|
||||
})
|
||||
.AddFlags(restPortSet, (p) =>
|
||||
{
|
||||
int restPort;
|
||||
if (int.TryParse(p, out restPort))
|
||||
{
|
||||
Config.RestApiPort = restPort;
|
||||
Console.WriteLine("Startup parameter overrode REST port.");
|
||||
break;
|
||||
case "-maxplayers":
|
||||
case "-players":
|
||||
Config.MaxSlots = Convert.ToInt32(parms[++i]);
|
||||
Console.WriteLine("Startup parameter overrode maximum player slot configuration value.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.AddFlags(playerSet, (p)=>
|
||||
{
|
||||
int slots;
|
||||
if (int.TryParse(p, out slots))
|
||||
{
|
||||
Config.MaxSlots = slots;
|
||||
Console.WriteLine("Startup parameter overrode maximum player slot configuration value.");
|
||||
}
|
||||
});
|
||||
|
||||
CliParser.ParseFromSource(parms);
|
||||
}
|
||||
|
||||
/// <summary>AuthToken - The auth token used by the /auth system to grant temporary superadmin access to new admins.</summary>
|
||||
|
|
@ -1014,7 +1006,8 @@ namespace TShockAPI
|
|||
if (player.TilePlaceThreshold >= Config.TilePlaceThreshold)
|
||||
{
|
||||
player.Disable("Reached TilePlace threshold", flags);
|
||||
lock (player.TilesCreated) {
|
||||
lock (player.TilesCreated)
|
||||
{
|
||||
TSPlayer.Server.RevertTiles(player.TilesCreated);
|
||||
player.TilesCreated.Clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackupManager.cs" />
|
||||
<Compile Include="CLI\CommandLineParser.cs" />
|
||||
<Compile Include="CLI\FlagSet.cs" />
|
||||
<Compile Include="DB\ProjectileManager.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="DB\TileManager.cs" />
|
||||
|
|
@ -201,7 +203,7 @@
|
|||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_IncrementBeforeBuild="False" BuildVersion_StartDate="2011/6/17" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_BuildAction="Both" BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" />
|
||||
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
|
|
|||
|
|
@ -1166,6 +1166,32 @@ namespace TShockAPI
|
|||
return points;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dumps information and optionally exits afterwards
|
||||
/// </summary>
|
||||
/// <param name="exit"></param>
|
||||
public void Dump(bool exit = true)
|
||||
{
|
||||
PrepareLangForDump();
|
||||
Lang.setLang(true);
|
||||
ConfigFile.DumpDescriptions();
|
||||
Permissions.DumpDescriptions();
|
||||
ServerSideCharacters.ServerSideConfig.DumpDescriptions();
|
||||
RestManager.DumpDescriptions();
|
||||
DumpBuffs("BuffList.txt");
|
||||
DumpItems("Items-1_0.txt", -48, 235);
|
||||
DumpItems("Items-1_1.txt", 235, 604);
|
||||
DumpItems("Items-1_2.txt", 604, 2749);
|
||||
DumpItems("Items-1_3.txt", 2749, Main.maxItemTypes);
|
||||
DumpNPCs("NPCs.txt");
|
||||
DumpProjectiles("Projectiles.txt");
|
||||
DumpPrefixes("Prefixes.txt");
|
||||
if (exit)
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
internal void PrepareLangForDump()
|
||||
{
|
||||
for(int i = 0; i < Main.recipe.Length; i++)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue