diff --git a/TShockAPI/CLI/CommandLineParser.cs b/TShockAPI/CLI/CommandLineParser.cs
new file mode 100644
index 00000000..84c34b94
--- /dev/null
+++ b/TShockAPI/CLI/CommandLineParser.cs
@@ -0,0 +1,306 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace TShockAPI.CLI
+{
+ ///
+ /// A simple command-line parser for retrieving basic information from a command-line. Array types are not supported
+ ///
+ public class CommandLineParser
+ {
+ private List _flags = new List();
+ private Dictionary _results = new Dictionary();
+ private string[] _source;
+
+ ///
+ /// Resets the CommandLineParser, removing any results and flags, and clearing the source
+ ///
+ ///
+ public CommandLineParser Reset()
+ {
+ _flags.Clear();
+ _results.Clear();
+ _source = null;
+
+ return this;
+ }
+
+ ///
+ /// Adds a flag to be parsed
+ ///
+ /// The flag to be added
+ /// Whether or not the flag is followed by an argument
+ public CommandLineParser AddFlag(string flag, bool noArgs = false)
+ {
+ FlagSet flags = new FlagSet(flag) { NoArgs = noArgs };
+ return AddFlags(flags);
+ }
+
+ ///
+ /// 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
+ ///
+ ///
+ ///
+ ///
+ public CommandLineParser AddFlag(string flag, Action callback)
+ {
+ FlagSet flags = new FlagSet(flag) { callback = callback };
+ return AddFlags(flags);
+ }
+
+ ///
+ /// 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
+ ///
+ ///
+ ///
+ ///
+ public CommandLineParser AddFlag(string flag, Action callback)
+ {
+ FlagSet flags = new FlagSet(flag) { NoArgs = true, callback = callback };
+ return AddFlags(flags);
+ }
+
+ ///
+ /// Adds a range of flags to be parsed
+ ///
+ /// The FlagSet to be added
+ ///
+ public CommandLineParser AddFlags(FlagSet flags)
+ {
+ if (_flags.Contains(flags))
+ {
+ return this;
+ }
+
+ _flags.Add(flags);
+
+ return this;
+ }
+
+ ///
+ /// 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
+ ///
+ /// The FlagSet to be added
+ /// An Action with a single string parameter. This parameter is the value passed to the flag
+ ///
+ public CommandLineParser AddFlags(FlagSet flags, Action callback)
+ {
+ flags.callback = callback;
+ return AddFlags(flags);
+ }
+
+ ///
+ /// 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
+ ///
+ /// The FlagSet to be added
+ /// An Action with no parameters.
+ ///
+ public CommandLineParser AddFlags(FlagSet flags, Action callback)
+ {
+ flags.callback = callback;
+ flags.NoArgs = true;
+ return AddFlags(flags);
+ }
+
+ ///
+ /// Adds a callback after a flag's parsing has been completed.
+ /// This method automatically attaches the callback to the last added flag
+ ///
+ /// An Action with no parameters.
+ ///
+ public CommandLineParser After(Action callback)
+ {
+ FlagSet flags = _flags.Last();
+ flags.continuation = callback;
+ return this;
+ }
+
+ ///
+ /// Gets the result of a FlagSet, cast to the given type parameter. Array types are not supported
+ ///
+ ///
+ ///
+ ///
+ public T Get(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);
+ }
+
+ ///
+ /// Parses the given source for flags registered with the parser
+ ///
+ ///
+ ///
+ 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)flags.callback).Invoke(argument);
+ }
+ else
+ {
+ _results.Add(flags, argument);
+ }
+ }
+ flags.continuation?.Invoke();
+ }
+
+ return this;
+ }
+
+ ///
+ /// Gets the result of a flag, cast to the given type parameter. Array types are not supported
+ ///
+ ///
+ ///
+ ///
+ public T Get(string flag)
+ {
+ FlagSet flags = _flags.FirstOrDefault(f => f.Contains(flag));
+ if (flags == null)
+ {
+ return default(T);
+ }
+
+ return Get(flags);
+ }
+
+ ///
+ /// Attempts to get the result of a flag, cast to the given type parameter. Array types are not supported
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool TryGet(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);
+ }
+
+ ///
+ /// Attempts to get the result of a FlagSet, cast to the given type parameter. Array types are not supported
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool TryGet(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;
+ }
+ }
+ }
+}
diff --git a/TShockAPI/CLI/FlagSet.cs b/TShockAPI/CLI/FlagSet.cs
new file mode 100644
index 00000000..71f4e07a
--- /dev/null
+++ b/TShockAPI/CLI/FlagSet.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace TShockAPI.CLI
+{
+ ///
+ /// Describes a set of flags that are responsible for one CL argument
+ ///
+ public class FlagSet : IEquatable
+ {
+ private IEnumerable _flags;
+
+ internal object callback;
+ internal Action continuation;
+
+ ///
+ /// Whether or not the set of flags represented by this FlagSet is followed by an argument
+ ///
+ public bool NoArgs { get; set; }
+
+ ///
+ /// Creates a new with the given flags
+ ///
+ /// Flags represented by this FlagSet
+ public FlagSet(params string[] flags)
+ {
+ if (flags == null)
+ {
+ throw new ArgumentNullException(nameof(flags));
+ }
+
+ _flags = flags.Select(f => f.ToLowerInvariant());
+ }
+
+ ///
+ /// Creates a new with the given flags and arguments option
+ ///
+ /// Flags represented by this FlagSet
+ /// Whether or not the flags specified will be followed by an argument
+ public FlagSet(string[] flags, bool noArgs) : this(flags)
+ {
+ NoArgs = noArgs;
+ }
+
+ ///
+ /// Determines whether or not this flag set contains the given flag
+ ///
+ ///
+ ///
+ public bool Contains(string flag)
+ {
+ return _flags.Contains(flag);
+ }
+
+ ///
+ /// Determines whether or not this flag set is equatable to another
+ ///
+ ///
+ ///
+ public bool Equals(FlagSet other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+
+ return other._flags == _flags;
+ }
+ }
+}
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index dcf3272e..fe4ad7e7 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -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
/// instance - Static reference to the TerrariaPlugin instance.
public static TerrariaPlugin instance;
///
+ /// Static reference to a used for simple command-line parsing
+ ///
+ public static CommandLineParser CliParser { get; } = new CommandLineParser();
+ ///
/// Used for implementing REST Tokens prior to the REST system starting up.
///
public static Dictionary RESTStartupTokens = new Dictionary();
@@ -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
/// parms - The array of arguments passed in through the command line.
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 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);
+ }*/
}
/// HandleCommandLinePostConfigLoad - Handles additional command line options after the config file is read.
/// parms - The array of arguments passed in through the command line.
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);
}
/// AuthToken - The auth token used by the /auth system to grant temporary superadmin access to new admins.
@@ -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();
}
@@ -1382,7 +1375,7 @@ namespace TShockAPI
}
}
}
-
+
/// OnLeave - Called when a player leaves the server.
/// args - The LeaveEventArgs object.
private void OnLeave(LeaveEventArgs args)
diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj
index aa0d44b4..9f610078 100644
--- a/TShockAPI/TShockAPI.csproj
+++ b/TShockAPI/TShockAPI.csproj
@@ -83,6 +83,8 @@
+
+
@@ -201,7 +203,7 @@
-
+