diff --git a/Server/CommandHandler.cs b/Server/CommandHandler.cs index 9a9634f..6dc5978 100644 --- a/Server/CommandHandler.cs +++ b/Server/CommandHandler.cs @@ -1,4 +1,5 @@ -namespace Server; +using System.Text; +namespace Server; public static class CommandHandler { public delegate Response Handler(string[] args); @@ -19,10 +20,39 @@ public static class CommandHandler { } } - public static Response GetResult(string input) { + /// + /// Modified by TheUbMunster + /// + public static Response GetResult(string input) + { try { string[] args = input.Split(' '); if (args.Length == 0) return "No command entered, see help command for valid commands"; + //this part is to allow single arguments that contain spaces (since the game seems to be able to handle usernames with spaces, we need to as well) + List newArgs = new List(); + newArgs.Add(args[0]); + for (int i = 1; i < args.Length; i++) { + if (args[i].Length == 0) continue; //empty string (>1 whitespace between arguments). + else if (args[i][0] == '\"') { + //concatenate args until a string ends with a quote + StringBuilder sb = new StringBuilder(); + i--; //fix off-by-one issue + do + { + i++; + sb.Append(args[i] + " "); //add space back removed by the string.Split(' ') + if (i >= args.Length) { + return "Unmatching quotes, make sure that whenever quotes are used, another quote is present to close it (no action was performed)."; + } + } while (args[i][^1] != '\"'); + newArgs.Add(sb.ToString(1, sb.Length - 3)); //remove quotes and extra space at the end. + } + else + { + newArgs.Add(args[i]); + } + } + args = newArgs.ToArray(); string commandName = args[0]; return Handlers.TryGetValue(commandName, out Handler? handler) ? handler(args[1..]) : $"Invalid command {args[0]}, see help command for valid commands"; } diff --git a/Server/Program.cs b/Server/Program.cs index 548d85b..045a05d 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -197,12 +197,15 @@ server.PacketHandler = (c, p) => { }; CommandHandler.RegisterCommand("rejoin", args => { + if (args.Length == 0) { + return "Usage: rejoin <* | usernames...>"; + } bool moreThanOne = false; StringBuilder builder = new StringBuilder(); - Client[] clients = (args.Length == 1 && args[0] == "*" - ? server.Clients.Where(c => - c.Connected && args.Any(x => c.Name.StartsWith(x) || (Guid.TryParse(x, out Guid result) && result == c.Id))) - : server.Clients.Where(c => c.Connected)).ToArray(); + Client[] clients = (args[0].Trim() == "*" + ? server.Clients.Where(c => c.Connected) + : server.Clients.Where(c => + c.Connected && args.Any(x => c.Name == x || (Guid.TryParse(x, out Guid result) && result == c.Id)))).ToArray(); foreach (Client user in clients) { if (moreThanOne) builder.Append(", "); builder.Append(user.Name); @@ -214,12 +217,15 @@ CommandHandler.RegisterCommand("rejoin", args => { }); CommandHandler.RegisterCommand("crash", args => { + if (args.Length == 0) { + return "Usage: crash <* | usernames...>"; + } bool moreThanOne = false; StringBuilder builder = new StringBuilder(); - Client[] clients = (args.Length == 1 && args[0] == "*" - ? server.Clients.Where(c => - c.Connected && args.Any(x => c.Name.StartsWith(x) || (Guid.TryParse(x, out Guid result) && result == c.Id))) - : server.Clients.Where(c => c.Connected)).ToArray(); + Client[] clients = (args[0].Trim() == "*" + ? server.Clients.Where(c => c.Connected) + : server.Clients.Where(c => + c.Connected && args.Any(x => c.Name == x || (Guid.TryParse(x, out Guid result) && result == c.Id)))).ToArray(); foreach (Client user in clients) { if (moreThanOne) builder.Append(", "); moreThanOne = true; @@ -239,13 +245,16 @@ CommandHandler.RegisterCommand("crash", args => { }); CommandHandler.RegisterCommand("ban", args => { + if (args.Length == 0) { + return "Usage: ban <* | usernames...>"; + } bool moreThanOne = false; StringBuilder builder = new StringBuilder(); - Client[] clients = (args.Length == 1 && args[0] == "*" - ? server.Clients.Where(c => - c.Connected && args.Any(x => c.Name.StartsWith(x) || (Guid.TryParse(x, out Guid result) && result == c.Id))) - : server.Clients.Where(c => c.Connected)).ToArray(); + Client[] clients = (args[0].Trim() == "*" + ? server.Clients.Where(c => c.Connected) + : server.Clients.Where(c => + c.Connected && args.Any(x => c.Name == x || (Guid.TryParse(x, out Guid result) && result == c.Id)))).ToArray(); foreach (Client user in clients) { if (moreThanOne) builder.Append(", "); moreThanOne = true; diff --git a/Server/Server.cs b/Server/Server.cs index dfe19cd..f312ea3 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -170,7 +170,6 @@ public class Server { ConnectPacket connect = new ConnectPacket(); connect.Deserialize(memory.Memory.Span[packetRange]); lock (Clients) { - client.Name = connect.ClientName; if (Clients.Count(x => x.Connected) == Settings.Instance.Server.MaxPlayers) { client.Logger.Error($"Turned away as server is at max clients"); memory.Dispose(); @@ -212,6 +211,7 @@ public class Server { throw new Exception($"Invalid connection type {connect.ConnectionType}"); } + client.Name = connect.ClientName; client.Connected = true; if (firstConn) { // do any cleanup required when it comes to new clients @@ -313,4 +313,4 @@ public class Server { header.Deserialize(data[..Constants.HeaderSize]); return header; } -} \ No newline at end of file +}