diff --git a/Source/Game/Chat/CommandArgs.cs b/Source/Game/Chat/CommandArgs.cs
index c84455acc..7ea2ea5f3 100644
--- a/Source/Game/Chat/CommandArgs.cs
+++ b/Source/Game/Chat/CommandArgs.cs
@@ -15,25 +15,42 @@
* along with this program. If not, see .
*/
-using Framework.Constants;
-using Framework.IO;
-using Game.Entities;
-using Game.Spells;
using System;
using System.Collections.Generic;
+using System.Reflection;
namespace Game.Chat
{
class CommandArgs
{
- public static bool Parse(out dynamic[] parsedArgs, CommandHandler handler, Type[] parameterTypes, StringArguments args)
+ static Dictionary> Parsers = new()
{
- parsedArgs = new dynamic[parameterTypes.Length];
+ { typeof(sbyte), args => args.NextSByte() },
+ { typeof(short), args => args.NextInt16() },
+ { typeof(int), args => args.NextInt32() },
+ { typeof(long), args => args.NextInt64() },
+ { typeof(byte), args => args.NextByte() },
+ { typeof(ushort), args => args.NextUInt16() },
+ { typeof(uint), args => args.NextUInt32() },
+ { typeof(ulong), args => args.NextUInt64() },
+ { typeof(float), args => args.NextSingle() },
+ { typeof(string), args => args.NextString() },
+ { typeof(bool), args => args.NextBoolean() },
+ { typeof(PlayerIdentifier), args => PlayerIdentifier.ParseFromString(args) },
+ { typeof(AccountIdentifier), args => AccountIdentifier.ParseFromString(args) },
+ { typeof(Tail), args => Tail.ParseFromString(args) },
+ };
+
+ public static bool Parse(out dynamic[] parsedArgs, CommandHandler handler, ParameterInfo[] parameterInfos, string tailCmd)
+ {
+ parsedArgs = new dynamic[parameterInfos.Length];
parsedArgs[0] = handler;
- for (var i = 1; i < parameterTypes.Length; i++)
+ CommandArguments args = new CommandArguments(tailCmd);
+
+ for (var i = 1; i < parameterInfos.Length; i++)
{
- if (!ParseArgument(out dynamic value, parameterTypes[i], args))
+ if (!ParseArgument(out dynamic value, parameterInfos[i], args))
return false;
parsedArgs[i] = value;
@@ -42,271 +59,339 @@ namespace Game.Chat
return true;
}
- static bool ParseArgument(out dynamic value, Type type, StringArguments args, bool IsOptional = false)
+ static bool ParseArgument(out dynamic value, ParameterInfo parameterInfo, CommandArguments args)
{
- value = default;
+ var parameterType = parameterInfo.ParameterType;
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(OptionalArg<>))
- return ParseArgument(out value, type.GetGenericArguments()[0], args, true);
-
- //todo remove me when all commands to changed to OptionalArg
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
- return ParseArgument(out value, Nullable.GetUnderlyingType(type), args, true);
-
- if (args.IsAtEnd())
- return IsOptional;
-
- if (Hyperlink.TryParse(out value, type, args))
+ if (Hyperlink.TryParse(out value, parameterType, args))
return true;
- if (type.IsEnum)
- type = type.GetEnumUnderlyingType();
+ bool isOptional = false;
- switch (Type.GetTypeCode(type))
+ var optionalArgAttribute = parameterInfo.GetCustomAttribute(true);
+ if (optionalArgAttribute != null)
+ isOptional = true;
+
+ if (parameterType.IsGenericType && parameterType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
- case TypeCode.SByte:
- value = args.NextSByte();
- break;
- case TypeCode.Int16:
- value = args.NextInt16();
- break;
- case TypeCode.Int32:
- value = args.NextInt32();
- break;
- case TypeCode.Int64:
- value = args.NextInt64();
- break;
- case TypeCode.Byte:
- value = args.NextByte();
- break;
- case TypeCode.UInt16:
- value = args.NextUInt16();
- break;
- case TypeCode.UInt32:
- value = args.NextUInt32();
- break;
- case TypeCode.UInt64:
- value = args.NextUInt64();
- break;
- case TypeCode.Single:
- value = args.NextSingle();
- break;
- case TypeCode.String:
- value = args.NextString();
- break;
- case TypeCode.Boolean:
- value = args.NextBoolean();
- break;
- case TypeCode.Char:
- value = args.NextChar();
- break;
- case TypeCode.Object:
- switch (type.Name)
- {
- case nameof(PlayerIdentifier):
- value = PlayerIdentifier.ParseFromString(args.NextString());
- break;
- case nameof(AccountIdentifier):
- value = AccountIdentifier.ParseFromString(args.NextString());
- break;
- default:
- return false;
- }
- break;
- default:
- return false;
+ parameterType = Nullable.GetUnderlyingType(parameterType);
+ isOptional = true;
}
+ if (parameterType.IsEnum)
+ parameterType = parameterType.GetEnumUnderlyingType();
+
+ var pos = args.GetCurrentPosition();
+
+ var result = Parsers[parameterType](args);
+ if (result != ParseResult.Ok)
+ {
+ if (!isOptional)
+ return false;
+ else
+ args.SetCurrentPosition(pos);
+ }
+
+ value = result.GetValue();
return true;
}
}
- class PlayerIdentifier
+ public enum ParseResult
{
- string _name;
- ObjectGuid _guid;
- Player _player;
+ Ok,
+ Error,
+ EndOfString
+ }
- public PlayerIdentifier(string name, ObjectGuid guid)
+ public struct ParseStringResult
+ {
+ ParseResult result;
+ dynamic value;
+
+ public ParseStringResult(ParseResult _result, dynamic _value = default)
{
- _name = name;
- _guid = guid;
+ result = _result;
+ value = _value;
}
- public PlayerIdentifier(Player player)
+ public dynamic GetValue() { return value; }
+
+ public static implicit operator ParseResult(ParseStringResult stringResult)
{
- _name = player.GetName();
- _guid = player.GetGUID();
- _player = player;
+ return stringResult.result;
}
- public string GetName() { return _name; }
- public ObjectGuid GetGUID() { return _guid; }
- public bool IsConnected() { return _player != null; }
- public Player GetConnectedPlayer() { return _player; }
-
- public static PlayerIdentifier FromTarget(CommandHandler handler)
+ public static implicit operator string(ParseStringResult stringResult)
{
- Player player = handler.GetPlayer();
- if (player != null)
- {
- Player target = player.GetSelectedPlayer();
- if (target != null)
- return new PlayerIdentifier(target);
- }
-
- return null;
- }
-
- public static PlayerIdentifier FromSelf(CommandHandler handler)
- {
- Player player = handler.GetPlayer();
- if (player != null)
- return new PlayerIdentifier(player);
-
- return null;
- }
-
- public static PlayerIdentifier FromTargetOrSelf(CommandHandler handler)
- {
- PlayerIdentifier fromTarget = FromTarget(handler);
- if (fromTarget != null)
- return fromTarget;
- else
- return FromSelf(handler);
- }
-
- public static PlayerIdentifier ParseFromString(string arg)
- {
- ulong guid = 0;
- string name;
- if (!Hyperlink.TryParse(out name, arg) || !ulong.TryParse(arg, out guid))
- name = arg;
-
- if (!name.IsEmpty())
- {
- ObjectManager.NormalizePlayerName(ref name);
- var player = Global.ObjAccessor.FindPlayerByName(name);
- if (player != null)
- return new PlayerIdentifier(player);
- else
- {
- var objectGuid = Global.CharacterCacheStorage.GetCharacterGuidByName(name);
- if (objectGuid.IsEmpty())
- return new PlayerIdentifier(name, objectGuid);
- }
- }
- else if (guid != 0)
- {
- var player = Global.ObjAccessor.FindPlayerByLowGUID(guid);
- if (player != null)
- return new PlayerIdentifier(player);
- }
-
- return null;
+ return stringResult.value;
}
}
- class AccountIdentifier
+ public sealed class CommandArguments
{
- uint _id;
- string _name;
- WorldSession _session;
+ static ParseStringResult ErrorResult = new(ParseResult.Error);
+ static ParseStringResult EndOfStringResult = new(ParseResult.EndOfString);
- public AccountIdentifier(WorldSession session)
+ public CommandArguments(string args)
{
- _id = session.GetAccountId();
- _name = session.GetAccountName();
- _session = session;
+ if (!args.IsEmpty())
+ activestring = args.TrimStart(' ');
+ activeposition = -1;
}
- public uint GetID() { return _id; }
- public string GetName() { return _name; }
- public bool IsConnected() { return _session != null; }
- public WorldSession GetConnectedSession() { return _session; }
-
- public static AccountIdentifier ParseFromString(string arg)
+ public CommandArguments(CommandArguments args)
{
- // try parsing as account name
- var session = Global.WorldMgr.FindSession(Global.AccountMgr.GetId(arg));
- if (session != null) // account with name exists, we are done
- return new AccountIdentifier(session);
-
- // try parsing as account id
- if (uint.TryParse(arg, out uint id))
- return null;
-
- session = Global.WorldMgr.FindSession(id);
- if (session != null)
- return new AccountIdentifier(session);
-
- return null;
+ activestring = args.activestring;
+ activeposition = args.activeposition;
+ Current = args.Current;
}
- public static AccountIdentifier FromTarget(CommandHandler handler)
+ public bool Empty()
{
- Player player = handler.GetPlayer();
- if (player != null)
+ return activestring.IsEmpty();
+ }
+
+ public void MoveToNextChar(char c)
+ {
+ for (var i = activeposition; i < activestring.Length; ++i)
+ if (activestring[i] == c)
+ break;
+ }
+
+ public ParseStringResult NextString(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return new ParseStringResult(ParseResult.EndOfString, "");
+
+ if (System.Text.RegularExpressions.Regex.IsMatch(Current, @"^[a-zA-Z]+$"))
+ return new ParseStringResult(ParseResult.Ok, Current);
+
+ return new ParseStringResult(ParseResult.Error, "");
+ }
+
+ public ParseStringResult NextBoolean(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ bool value;
+ if (bool.TryParse(Current, out value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ if ((Current == "1") || Current.Equals("y", StringComparison.OrdinalIgnoreCase) || Current.Equals("on", StringComparison.OrdinalIgnoreCase) || Current.Equals("yes", StringComparison.OrdinalIgnoreCase) || Current.Equals("true", StringComparison.OrdinalIgnoreCase))
+ return new ParseStringResult(ParseResult.Ok, true);
+ if ((Current == "0") || Current.Equals("n", StringComparison.OrdinalIgnoreCase) || Current.Equals("off", StringComparison.OrdinalIgnoreCase) || Current.Equals("no", StringComparison.OrdinalIgnoreCase) || Current.Equals("false", StringComparison.OrdinalIgnoreCase))
+ return new ParseStringResult(ParseResult.Ok, false);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextChar(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (char.TryParse(Current, out char value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextByte(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (byte.TryParse(Current, out byte value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextSByte(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (sbyte.TryParse(Current, out sbyte value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextUInt16(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (ushort.TryParse(Current, out ushort value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextInt16(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (short.TryParse(Current, out short value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextUInt32(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (uint.TryParse(Current, out uint value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextInt32(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (int.TryParse(Current, out int value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextUInt64(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (ulong.TryParse(Current, out ulong value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextInt64(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (long.TryParse(Current, out long value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextSingle(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (float.TryParse(Current, out float value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextDouble(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (double.TryParse(Current, out double value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public ParseStringResult NextDecimal(string delimiters = " ")
+ {
+ if (!MoveNext(delimiters))
+ return EndOfStringResult;
+
+ if (decimal.TryParse(Current, out decimal value))
+ return new ParseStringResult(ParseResult.Ok, value);
+
+ return ErrorResult;
+ }
+
+ public void AlignToNextChar()
+ {
+ while (activeposition < activestring.Length && activestring[activeposition] != ' ')
+ activeposition++;
+ }
+
+ public char this[int index]
+ {
+ get { return activestring[index]; }
+ }
+
+ public string GetString()
+ {
+ return activestring;
+ }
+
+ public void Reset()
+ {
+ activeposition = -1;
+ Current = null;
+ }
+
+ public bool IsAtEnd()
+ {
+ return activestring.IsEmpty() || activeposition == activestring.Length;
+ }
+
+ public int GetCurrentPosition()
+ {
+ return activeposition;
+ }
+
+ public void SetCurrentPosition(int currentPosition)
+ {
+ activeposition = currentPosition;
+ }
+
+ bool MoveNext(string delimiters)
+ {
+ //the stringtotokenize was never set:
+ if (activestring == null)
+ return false;
+
+ //all tokens have already been extracted:
+ if (activeposition == activestring.Length)
+ return false;
+
+ //bypass delimiters:
+ activeposition++;
+ while (activeposition < activestring.Length && delimiters.IndexOf(activestring[activeposition]) > -1)
{
- Player target = player.GetSelectedPlayer();
- if (target != null)
- {
- WorldSession session = target.GetSession();
- if (session != null)
- return new AccountIdentifier(session);
- }
+ activeposition++;
}
- return null;
- }
- }
+ //only delimiters were left, so return null:
+ if (activeposition == activestring.Length)
+ return false;
- struct OptionalArg
- {
- private bool _hasValue;
- public T Value;
+ //get starting position of string to return:
+ int startingposition = activeposition;
- public OptionalArg(T value)
- {
- Value = value;
- _hasValue = true;
+ //read until next delimiter:
+ do
+ {
+ activeposition++;
+ } while (activeposition < activestring.Length && delimiters.IndexOf(activestring[activeposition]) == -1);
+
+ Current = activestring.Substring(startingposition, activeposition - startingposition);
+ return true;
}
- public bool HasValue
- {
- get { return _hasValue; }
- }
-
- public void Set(T value)
- {
- Value = value;
- _hasValue = true;
- }
-
- public void Clear()
- {
- _hasValue = false;
- Value = default;
- }
-
- public T ValueOr(T otherValue)
- {
- return HasValue ? Value : otherValue;
- }
-
- public static explicit operator T(OptionalArg optional)
- {
- return optional.Value;
- }
-
- public static implicit operator OptionalArg(T value)
- {
- return new OptionalArg(value);
- }
-
- public Type GetValueType()
- {
- return typeof(T);
- }
+ private string activestring;
+ private int activeposition;
+ private string Current;
}
}
diff --git a/Source/Game/Chat/CommandAttribute.cs b/Source/Game/Chat/CommandAttribute.cs
index ee5fcc306..d0f278c61 100644
--- a/Source/Game/Chat/CommandAttribute.cs
+++ b/Source/Game/Chat/CommandAttribute.cs
@@ -76,4 +76,7 @@ namespace Game.Chat
public CommandNonGroupAttribute(string command, CypherStrings help, RBACPermissions rbac, bool allowConsole = false) : base(command, help, rbac, allowConsole) { }
public CommandNonGroupAttribute(string command, RBACPermissions rbac, bool allowConsole = false) : base(command, rbac, allowConsole) { }
}
+
+ [AttributeUsage(AttributeTargets.Parameter)]
+ public class OptionalArgAttribute : Attribute { }
}
diff --git a/Source/Game/Chat/CommandManager.cs b/Source/Game/Chat/CommandManager.cs
index 0be09c559..b76eda723 100644
--- a/Source/Game/Chat/CommandManager.cs
+++ b/Source/Game/Chat/CommandManager.cs
@@ -114,14 +114,17 @@ namespace Game.Chat
foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic))
{
- CommandAttribute commandAttribute = method.GetCustomAttribute(false);
- if (commandAttribute == null)
+ var commandAttributes = method.GetCustomAttributes(false).ToArray();
+ if (commandAttributes.Length == 0)
continue;
- if (commandAttribute.GetType() == typeof(CommandNonGroupAttribute))
- continue;
+ foreach (var commandAttribute in commandAttributes)
+ {
+ if (commandAttribute.GetType() == typeof(CommandNonGroupAttribute))
+ continue;
- command.AddSubCommand(new ChatCommandNode(commandAttribute, method));
+ command.AddSubCommand(new ChatCommandNode(commandAttribute, method));
+ }
}
}
@@ -161,7 +164,7 @@ namespace Game.Chat
public SortedDictionary _subCommands = new();
MethodInfo _methodInfo;
- Type[] parameterTypes;
+ ParameterInfo[] parameters;
public ChatCommandNode(CommandAttribute attribute)
{
@@ -173,7 +176,7 @@ namespace Game.Chat
public ChatCommandNode(CommandAttribute attribute, MethodInfo methodInfo) : this(attribute)
{
_methodInfo = methodInfo;
- parameterTypes = (from parameter in methodInfo.GetParameters() select parameter.ParameterType).ToArray();
+ parameters = methodInfo.GetParameters();
}
public static bool TryExecuteCommand(CommandHandler handler, string cmdStr)
@@ -221,7 +224,7 @@ namespace Game.Chat
if (cmd != null)
{ /* if we matched a command at some point, invoke it */
handler._sentErrorMessage = false;
- if (cmd.IsInvokerVisible(handler) && cmd.Invoke(handler, new StringArguments(oldTail)))
+ if (cmd.IsInvokerVisible(handler) && cmd.Invoke(handler, oldTail))
{ /* invocation succeeded, log this */
if (!handler.IsConsole())
LogCommandUsage(handler.GetSession(), (uint)cmd._permission.RequiredPermission, cmdStr);
@@ -283,7 +286,12 @@ namespace Game.Chat
{
handler.SendSysMessage(CypherStrings.AvailableCmds);
foreach (var (name, command) in map)
+ {
+ if (!command.IsVisible(handler))
+ continue;
+
handler.SendSysMessage(command.HasVisibleSubCommands(handler) ? CypherStrings.SubcmdsListEntryEllipsis : CypherStrings.SubcmdsListEntry, name);
+ }
}
else
handler.SendSysMessage(CypherStrings.CmdInvalid, cmdStr);
@@ -390,7 +398,7 @@ namespace Game.Chat
_helpText = command._helpText;
_helpString = command._helpString;
_methodInfo = command._methodInfo;
- parameterTypes = command.parameterTypes;
+ parameters = command.parameters;
}
else
{
@@ -399,13 +407,13 @@ namespace Game.Chat
}
}
- public bool Invoke(CommandHandler handler, StringArguments args)
+ public bool Invoke(CommandHandler handler, string args)
{
- if (parameterTypes.Contains(typeof(StringArguments)))//Old system, can remove once all commands are changed.
- return (bool)_methodInfo.Invoke(null, new object[] { handler, args });
+ if (parameters.Any(p => p.ParameterType == typeof(StringArguments)))//Old system, can remove once all commands are changed.
+ return (bool)_methodInfo.Invoke(null, new object[] { handler, new StringArguments(args) });
else
{
- if (CommandArgs.Parse(out dynamic[] parseArgs, handler, parameterTypes, args))
+ if (CommandArgs.Parse(out dynamic[] parseArgs, handler, parameters, args))
return (bool)_methodInfo.Invoke(null, parseArgs);
return false;
diff --git a/Source/Game/Chat/CommandTags.cs b/Source/Game/Chat/CommandTags.cs
new file mode 100644
index 000000000..51278ca9d
--- /dev/null
+++ b/Source/Game/Chat/CommandTags.cs
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2012-2020 CypherCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Game.Entities;
+using System;
+
+namespace Game.Chat
+{
+ class PlayerIdentifier
+ {
+ string _name;
+ ObjectGuid _guid;
+ Player _player;
+
+ public PlayerIdentifier(string name, ObjectGuid guid)
+ {
+ _name = name;
+ _guid = guid;
+ }
+
+ public PlayerIdentifier(Player player)
+ {
+ _name = player.GetName();
+ _guid = player.GetGUID();
+ _player = player;
+ }
+
+ public string GetName() { return _name; }
+ public ObjectGuid GetGUID() { return _guid; }
+ public bool IsConnected() { return _player != null; }
+ public Player GetConnectedPlayer() { return _player; }
+
+ public static PlayerIdentifier FromTarget(CommandHandler handler)
+ {
+ Player player = handler.GetPlayer();
+ if (player != null)
+ {
+ Player target = player.GetSelectedPlayer();
+ if (target != null)
+ return new PlayerIdentifier(target);
+ }
+
+ return null;
+ }
+
+ public static PlayerIdentifier FromSelf(CommandHandler handler)
+ {
+ Player player = handler.GetPlayer();
+ if (player != null)
+ return new PlayerIdentifier(player);
+
+ return null;
+ }
+
+ public static PlayerIdentifier FromTargetOrSelf(CommandHandler handler)
+ {
+ PlayerIdentifier fromTarget = FromTarget(handler);
+ if (fromTarget != null)
+ return fromTarget;
+ else
+ return FromSelf(handler);
+ }
+
+ public static ParseStringResult ParseFromString(CommandArguments args)
+ {
+ var result = args.NextString();
+ if (result != ParseResult.Ok)
+ return new ParseStringResult(ParseResult.Error);
+
+ string arg = result.GetValue();
+
+ ulong guid = 0;
+ string name;
+ if (!Hyperlink.TryParse(out name, arg) || !ulong.TryParse(arg, out guid))
+ name = arg;
+
+ if (!name.IsEmpty())
+ {
+ ObjectManager.NormalizePlayerName(ref name);
+ var player = Global.ObjAccessor.FindPlayerByName(name);
+ if (player != null)
+ return new ParseStringResult(ParseResult.Ok, new PlayerIdentifier(player));
+ else
+ {
+ var objectGuid = Global.CharacterCacheStorage.GetCharacterGuidByName(name);
+ if (objectGuid.IsEmpty())
+ return new ParseStringResult(ParseResult.Ok, new PlayerIdentifier(name, objectGuid));
+ }
+ }
+ else if (guid != 0)
+ {
+ var player = Global.ObjAccessor.FindPlayerByLowGUID(guid);
+ if (player != null)
+ return new ParseStringResult(ParseResult.Ok, new PlayerIdentifier(player));
+ }
+
+ return new ParseStringResult(ParseResult.Error);
+ }
+ }
+
+ class AccountIdentifier
+ {
+ uint _id;
+ string _name;
+ WorldSession _session;
+
+ public AccountIdentifier(WorldSession session)
+ {
+ _id = session.GetAccountId();
+ _name = session.GetAccountName();
+ _session = session;
+ }
+
+ public uint GetID() { return _id; }
+ public string GetName() { return _name; }
+ public bool IsConnected() { return _session != null; }
+ public WorldSession GetConnectedSession() { return _session; }
+
+ public static ParseStringResult ParseFromString(CommandArguments args)
+ {
+ var result = args.NextString();
+ if (result != ParseResult.Ok)
+ return new ParseStringResult(ParseResult.Error);
+
+ // try parsing as account name
+ var session = Global.WorldMgr.FindSession(Global.AccountMgr.GetId(result.GetValue()));
+ if (session != null) // account with name exists, we are done
+ return new ParseStringResult(ParseResult.Ok, new AccountIdentifier(session));
+
+ // try parsing as account id
+ if (!uint.TryParse(result.GetValue(), out uint id))
+ return new ParseStringResult(ParseResult.Error);
+
+ session = Global.WorldMgr.FindSession(id);
+ if (session != null)
+ return new ParseStringResult(ParseResult.Ok, new AccountIdentifier(session));
+
+ return new ParseStringResult(ParseResult.Error);
+ }
+
+ public static AccountIdentifier FromTarget(CommandHandler handler)
+ {
+ Player player = handler.GetPlayer();
+ if (player != null)
+ {
+ Player target = player.GetSelectedPlayer();
+ if (target != null)
+ {
+ WorldSession session = target.GetSession();
+ if (session != null)
+ return new AccountIdentifier(session);
+ }
+ }
+
+ return null;
+ }
+ }
+
+ struct Tail
+ {
+ string str;
+
+ public Tail(CommandArguments args)
+ {
+ str = args.NextString("").GetValue();
+ }
+
+ public bool IsEmpty() { return str.IsEmpty(); }
+
+ public static implicit operator string(Tail tail)
+ {
+ return tail.str;
+ }
+
+ public static ParseStringResult ParseFromString(CommandArguments args)
+ {
+ return new ParseStringResult(ParseResult.Ok, new Tail(args));
+ }
+ }
+}
diff --git a/Source/Game/Chat/Commands/AccountCommands.cs b/Source/Game/Chat/Commands/AccountCommands.cs
index e6917335a..f20d8b9d4 100644
--- a/Source/Game/Chat/Commands/AccountCommands.cs
+++ b/Source/Game/Chat/Commands/AccountCommands.cs
@@ -87,7 +87,7 @@ namespace Game.Chat
}
[Command("create", CypherStrings.CommandAccCreateHelp, RBACPermissions.CommandAccountCreate, true)]
- static bool HandleAccountCreateCommand(CommandHandler handler, string accountName, string password, OptionalArg email)
+ static bool HandleAccountCreateCommand(CommandHandler handler, string accountName, string password, [OptionalArg]string email)
{
if (accountName.Contains("@"))
{
@@ -95,7 +95,7 @@ namespace Game.Chat
return false;
}
- AccountOpResult result = Global.AccountMgr.CreateAccount(accountName, password, email.ValueOr(""));
+ AccountOpResult result = Global.AccountMgr.CreateAccount(accountName, password, email);
switch (result)
{
case AccountOpResult.Ok:
@@ -221,7 +221,7 @@ namespace Game.Chat
}
[Command("password", CypherStrings.CommandAccPasswordHelp, RBACPermissions.CommandAccountPassword)]
- static bool HandleAccountPasswordCommand(CommandHandler handler, string oldPassword, string newPassword, string confirmPassword, string confirmEmail)
+ static bool HandleAccountPasswordCommand(CommandHandler handler, string oldPassword, string newPassword, string confirmPassword, [OptionalArg] string confirmEmail)
{
// First, we check config. What security type (sec type) is it ? Depending on it, the command branches out
uint pwConfig = WorldConfig.GetUIntValue(WorldCfg.AccPasschangesec); // 0 - PW_NONE, 1 - PW_EMAIL, 2 - PW_RBAC
@@ -441,7 +441,7 @@ namespace Game.Chat
class AccountSetCommands
{
[Command("addon", CypherStrings.CommandAccSetAddonHelp, RBACPermissions.CommandAccountSetAddon, true)]
- static bool HandleAccountSetAddonCommand(CommandHandler handler, string accountName, byte expansion)
+ static bool HandleAccountSetAddonCommand(CommandHandler handler, [OptionalArg] string accountName, byte expansion)
{
uint accountId;
if (!accountName.IsEmpty())
@@ -486,12 +486,6 @@ namespace Game.Chat
return true;
}
- [Command("gmlevel", CypherStrings.CommandAccSetSeclevelHelp, RBACPermissions.CommandAccountSetSecLevel, true)]
- static bool HandleAccountSetGmLevelCommand(CommandHandler handler, string accountName, byte securityLevel, int realmId = -1)
- {
- return HandleAccountSetSecLevelCommand(handler, accountName, securityLevel, realmId);
- }
-
[Command("password", CypherStrings.CommandAccSetPasswordHelp, RBACPermissions.CommandAccountSetPassword, true)]
static bool HandleAccountSetPasswordCommand(CommandHandler handler, string accountName, string password, string confirmPassword)
{
@@ -534,7 +528,8 @@ namespace Game.Chat
}
[Command("seclevel", CypherStrings.CommandAccSetSeclevelHelp, RBACPermissions.CommandAccountSetSecLevel, true)]
- static bool HandleAccountSetSecLevelCommand(CommandHandler handler, string accountName, byte securityLevel, int? realmId)
+ [Command("gmlevel", CypherStrings.CommandAccSetSeclevelHelp, RBACPermissions.CommandAccountSetSecLevel, true)]
+ static bool HandleAccountSetSecLevelCommand(CommandHandler handler, [OptionalArg] string accountName, byte securityLevel, int? realmId)
{
uint accountId;
if (!accountName.IsEmpty())
@@ -698,7 +693,5 @@ namespace Game.Chat
}
}
}
-
-
}
}
diff --git a/Source/Game/Chat/Commands/BNetAccountCommands.cs b/Source/Game/Chat/Commands/BNetAccountCommands.cs
index a02d9e077..67a25b246 100644
--- a/Source/Game/Chat/Commands/BNetAccountCommands.cs
+++ b/Source/Game/Chat/Commands/BNetAccountCommands.cs
@@ -156,7 +156,7 @@ namespace Game.Chat.Commands
handler.SendSysMessage("----------------------------------------------------");
do
{
- handler.SendSysMessage("| {10:0} | {1} | {2} |", accountList.Read(0), accountList.Read(1), formatDisplayName(accountList.Read(1)));
+ handler.SendSysMessage("| {0,10} | {1,16} | {2,16} |", accountList.Read(0), accountList.Read(1), formatDisplayName(accountList.Read(1)));
} while (accountList.NextRow());
handler.SendSysMessage("----------------------------------------------------");
}
diff --git a/Source/Game/Chat/Commands/CastCommands.cs b/Source/Game/Chat/Commands/CastCommands.cs
index 77faa4457..867da7207 100644
--- a/Source/Game/Chat/Commands/CastCommands.cs
+++ b/Source/Game/Chat/Commands/CastCommands.cs
@@ -27,7 +27,7 @@ namespace Game.Chat
class CastCommands
{
[Command("", RBACPermissions.CommandCast)]
- static bool HandleCastCommand(CommandHandler handler, uint spellId, string triggeredStr)
+ static bool HandleCastCommand(CommandHandler handler, uint spellId, [OptionalArg] string triggeredStr)
{
Unit target = handler.GetSelectedUnit();
if (!target)
@@ -48,7 +48,7 @@ namespace Game.Chat
}
[Command("back", RBACPermissions.CommandCastBack)]
- static bool HandleCastBackCommand(CommandHandler handler, uint spellId, string triggeredStr)
+ static bool HandleCastBackCommand(CommandHandler handler, uint spellId, [OptionalArg] string triggeredStr)
{
Creature caster = handler.GetSelectedCreature();
if (!caster)
@@ -70,7 +70,7 @@ namespace Game.Chat
}
[Command("dist", RBACPermissions.CommandCastDist)]
- static bool HandleCastDistCommand(CommandHandler handler, uint spellId, float dist, string triggeredStr)
+ static bool HandleCastDistCommand(CommandHandler handler, uint spellId, float dist, [OptionalArg] string triggeredStr)
{
if (CheckSpellExistsAndIsValid(handler, spellId))
return false;
@@ -88,7 +88,7 @@ namespace Game.Chat
}
[Command("self", RBACPermissions.CommandCastSelf)]
- static bool HandleCastSelfCommand(CommandHandler handler, uint spellId, string triggeredStr)
+ static bool HandleCastSelfCommand(CommandHandler handler, uint spellId, [OptionalArg] string triggeredStr)
{
Unit target = handler.GetSelectedUnit();
if (!target)
@@ -110,7 +110,7 @@ namespace Game.Chat
}
[Command("target", RBACPermissions.CommandCastTarget)]
- static bool HandleCastTargetCommad(CommandHandler handler, uint spellId, string triggeredStr)
+ static bool HandleCastTargetCommad(CommandHandler handler, uint spellId, [OptionalArg] string triggeredStr)
{
Creature caster = handler.GetSelectedCreature();
if (!caster)
@@ -138,7 +138,7 @@ namespace Game.Chat
}
[Command("dest", RBACPermissions.CommandCastDest)]
- static bool HandleCastDestCommand(CommandHandler handler, uint spellId, float x, float y, float z, string triggeredStr)
+ static bool HandleCastDestCommand(CommandHandler handler, uint spellId, float x, float y, float z, [OptionalArg] string triggeredStr)
{
Unit caster = handler.GetSelectedUnit();
if (!caster)
diff --git a/Source/Game/Chat/Commands/CharacterCommands.cs b/Source/Game/Chat/Commands/CharacterCommands.cs
index 1f2c357c9..9040e93d3 100644
--- a/Source/Game/Chat/Commands/CharacterCommands.cs
+++ b/Source/Game/Chat/Commands/CharacterCommands.cs
@@ -77,7 +77,7 @@ namespace Game.Chat
//rename characters
[Command("rename", RBACPermissions.CommandCharacterRename, true)]
- static bool HandleCharacterRenameCommand(CommandHandler handler, PlayerIdentifier player, string newName)
+ static bool HandleCharacterRenameCommand(CommandHandler handler, PlayerIdentifier player, [OptionalArg] string newName)
{
if (player == null && !newName.IsEmpty())
return false;
@@ -469,7 +469,7 @@ namespace Game.Chat
}
[Command("list", RBACPermissions.CommandCharacterDeletedList, true)]
- static bool HandleCharacterDeletedListCommand(CommandHandler handler, string needle)
+ static bool HandleCharacterDeletedListCommand(CommandHandler handler, [OptionalArg] string needle)
{
List foundList = new();
if (!GetDeletedCharacterInfoList(foundList, needle))
@@ -488,7 +488,7 @@ namespace Game.Chat
}
[Command("restore", RBACPermissions.CommandCharacterDeletedRestore, true)]
- static bool HandleCharacterDeletedRestoreCommand(CommandHandler handler, string needle, string newCharName, AccountIdentifier newAccount)
+ static bool HandleCharacterDeletedRestoreCommand(CommandHandler handler, string needle, [OptionalArg] string newCharName, AccountIdentifier newAccount)
{
List foundList = new();
if (!GetDeletedCharacterInfoList(foundList, needle))
@@ -725,7 +725,7 @@ namespace Game.Chat
class PdumpCommand
{
[Command("copy", RBACPermissions.CommandPdumpCopy, true)]
- static bool HandlePDumpCopyCommand(CommandHandler handler, string playerName, string accountName, string characterName, ulong? characterGUID)
+ static bool HandlePDumpCopyCommand(CommandHandler handler, PlayerIdentifier player, AccountIdentifier account, [OptionalArg] string characterName, ulong? characterGUID)
{
/*
std::string name;
@@ -771,7 +771,7 @@ namespace Game.Chat
}
[Command("load", RBACPermissions.CommandPdumpLoad, true)]
- static bool HandlePDumpLoadCommand(CommandHandler handler, string fileName, string accountName, string characterName, ulong? characterGuid)
+ static bool HandlePDumpLoadCommand(CommandHandler handler, string fileName, AccountIdentifier account, [OptionalArg] string characterName, ulong? characterGuid)
{
/*
if (!AccountMgr.normalizeString(accountName))
diff --git a/Source/Game/Chat/Commands/LearnCommands.cs b/Source/Game/Chat/Commands/LearnCommands.cs
index a0b3729a0..c486f641c 100644
--- a/Source/Game/Chat/Commands/LearnCommands.cs
+++ b/Source/Game/Chat/Commands/LearnCommands.cs
@@ -149,7 +149,7 @@ namespace Game.Chat.Commands
}
[Command("recipes", CypherStrings.CommandLearnAllRecipesHelp, RBACPermissions.CommandLearnAllRecipes)]
- static bool HandleLearnAllRecipesCommand(CommandHandler handler, string namePart)
+ static bool HandleLearnAllRecipesCommand(CommandHandler handler, Tail namePart)
{
// Learns all recipes of specified profession and sets skill to max
// Example: .learn all_recipes enchanting
diff --git a/Source/Game/Chat/Commands/ListCommands.cs b/Source/Game/Chat/Commands/ListCommands.cs
index 1aa935baa..8678f7ea9 100644
--- a/Source/Game/Chat/Commands/ListCommands.cs
+++ b/Source/Game/Chat/Commands/ListCommands.cs
@@ -578,7 +578,7 @@ namespace Game.Chat.Commands
}
[Command("name", RBACPermissions.CommandListAuras)]
- static bool HandleListAurasByNameCommand(CommandHandler handler, string namePart)
+ static bool HandleListAurasByNameCommand(CommandHandler handler, Tail namePart)
{
return ListAurasCommand(handler, null, namePart);
}
diff --git a/Source/Game/Chat/Commands/MessageCommands.cs b/Source/Game/Chat/Commands/MessageCommands.cs
index 32f70848b..d92d28869 100644
--- a/Source/Game/Chat/Commands/MessageCommands.cs
+++ b/Source/Game/Chat/Commands/MessageCommands.cs
@@ -28,7 +28,7 @@ namespace Game.Chat
class MessageCommands
{
[CommandNonGroup("nameannounce", RBACPermissions.CommandNameannounce, true)]
- static bool HandleNameAnnounceCommand(CommandHandler handler, string message)
+ static bool HandleNameAnnounceCommand(CommandHandler handler, Tail message)
{
if (message.IsEmpty())
return false;
@@ -43,7 +43,7 @@ namespace Game.Chat
}
[CommandNonGroup("gmnameannounce", RBACPermissions.CommandGmnameannounce, true)]
- static bool HandleGMNameAnnounceCommand(CommandHandler handler, string message)
+ static bool HandleGMNameAnnounceCommand(CommandHandler handler, Tail message)
{
if (message.IsEmpty())
return false;
@@ -58,7 +58,7 @@ namespace Game.Chat
}
[CommandNonGroup("announce", RBACPermissions.CommandAnnounce, true)]
- static bool HandleAnnounceCommand(CommandHandler handler, string message)
+ static bool HandleAnnounceCommand(CommandHandler handler, Tail message)
{
if (message.IsEmpty())
return false;
@@ -68,7 +68,7 @@ namespace Game.Chat
}
[CommandNonGroup("gmannounce", RBACPermissions.CommandGmannounce, true)]
- static bool HandleGMAnnounceCommand(CommandHandler handler, string message)
+ static bool HandleGMAnnounceCommand(CommandHandler handler, Tail message)
{
if (message.IsEmpty())
return false;
@@ -78,7 +78,7 @@ namespace Game.Chat
}
[CommandNonGroup("notify", RBACPermissions.CommandNotify, true)]
- static bool HandleNotifyCommand(CommandHandler handler, string message)
+ static bool HandleNotifyCommand(CommandHandler handler, Tail message)
{
if (message.IsEmpty())
return false;
@@ -92,7 +92,7 @@ namespace Game.Chat
}
[CommandNonGroup("gmnotify", RBACPermissions.CommandGmnotify, true)]
- static bool HandleGMNotifyCommand(CommandHandler handler, string message)
+ static bool HandleGMNotifyCommand(CommandHandler handler, Tail message)
{
if (message.IsEmpty())
return false;
@@ -106,7 +106,7 @@ namespace Game.Chat
}
[CommandNonGroup("whispers", RBACPermissions.CommandWhispers)]
- static bool HandleWhispersCommand(CommandHandler handler, bool? operationArg)
+ static bool HandleWhispersCommand(CommandHandler handler, bool? operationArg, [OptionalArg] string playerNameArg)
{
if (!operationArg.HasValue)
{
@@ -118,6 +118,7 @@ namespace Game.Chat
{
handler.GetSession().GetPlayer().SetAcceptWhispers(true);
handler.SendSysMessage(CypherStrings.CommandWhisperon);
+ return true;
}
else
{
@@ -125,9 +126,33 @@ namespace Game.Chat
handler.GetSession().GetPlayer().ClearWhisperWhiteList();
handler.GetSession().GetPlayer().SetAcceptWhispers(false);
handler.SendSysMessage(CypherStrings.CommandWhisperoff);
+ return true;
}
- return true;
+ //todo fix me
+ /*if (operationArg->holds_alternative < EXACT_SEQUENCE("remove") > ())
+ {
+ if (!playerNameArg)
+ return false;
+
+ if (normalizePlayerName(*playerNameArg))
+ {
+ if (Player * player = ObjectAccessor::FindPlayerByName(*playerNameArg))
+ {
+ handler->GetSession()->GetPlayer()->RemoveFromWhisperWhiteList(player->GetGUID());
+ handler->PSendSysMessage(LANG_COMMAND_WHISPEROFFPLAYER, playerNameArg->c_str());
+ return true;
+ }
+ else
+ {
+ handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND, playerNameArg->c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ }
+ handler.SendSysMessage(CypherStrings.UseBol);
+ return false;*/
}
}
diff --git a/Source/Game/Chat/Commands/MiscCommands.cs b/Source/Game/Chat/Commands/MiscCommands.cs
index 0e3b0ba14..056a1ebc6 100644
--- a/Source/Game/Chat/Commands/MiscCommands.cs
+++ b/Source/Game/Chat/Commands/MiscCommands.cs
@@ -733,10 +733,10 @@ namespace Game.Chat
}
[CommandNonGroup("help", RBACPermissions.CommandHelp, true)]
- static bool HandleHelpCommand(CommandHandler handler, OptionalArg cmd)
+ static bool HandleHelpCommand(CommandHandler handler, Tail cmd)
{
- ChatCommandNode.SendCommandHelpFor(handler, cmd.ValueOr(""));
- if (!cmd.HasValue)
+ ChatCommandNode.SendCommandHelpFor(handler, cmd);
+ if (cmd.IsEmpty())
ChatCommandNode.SendCommandHelpFor(handler, "help");
return true;
@@ -835,7 +835,7 @@ namespace Game.Chat
}
[CommandNonGroup("linkgrave", RBACPermissions.CommandLinkgrave)]
- static bool HandleLinkGraveCommand(CommandHandler handler, uint graveyardId, string teamArg)
+ static bool HandleLinkGraveCommand(CommandHandler handler, uint graveyardId, [OptionalArg] string teamArg)
{
Team team;
if (teamArg.IsEmpty())
@@ -1005,10 +1005,11 @@ namespace Game.Chat
// mute player for the specified duration
[CommandNonGroup("mute", RBACPermissions.CommandMute, true)]
- static bool HandleMuteCommand(CommandHandler handler, PlayerIdentifier player, uint muteTime, string muteReason)
+ static bool HandleMuteCommand(CommandHandler handler, PlayerIdentifier player, uint muteTime, Tail muteReason)
{
+ string muteReasonStr = muteReason;
if (muteReason.IsEmpty())
- muteReason = handler.GetCypherString(CypherStrings.NoReason);
+ muteReasonStr = handler.GetCypherString(CypherStrings.NoReason);
if (player == null)
player = PlayerIdentifier.FromTarget(handler);
@@ -1053,7 +1054,7 @@ namespace Game.Chat
stmt.AddValue(0, -(muteTime * Time.Minute));
}
- stmt.AddValue(1, muteReason);
+ stmt.AddValue(1, muteReasonStr);
stmt.AddValue(2, muteBy);
stmt.AddValue(3, accountId);
DB.Login.Execute(stmt);
@@ -1062,21 +1063,21 @@ namespace Game.Chat
stmt.AddValue(0, accountId);
stmt.AddValue(1, muteTime);
stmt.AddValue(2, muteBy);
- stmt.AddValue(3, muteReason);
+ stmt.AddValue(3, muteReasonStr);
DB.Login.Execute(stmt);
string nameLink = handler.PlayerLink(player.GetName());
if (WorldConfig.GetBoolValue(WorldCfg.ShowMuteInWorld))
- Global.WorldMgr.SendWorldText(CypherStrings.CommandMutemessageWorld, muteBy, nameLink, muteTime, muteReason);
+ Global.WorldMgr.SendWorldText(CypherStrings.CommandMutemessageWorld, muteBy, nameLink, muteTime, muteReasonStr);
if (target)
{
- target.SendSysMessage(CypherStrings.YourChatDisabled, muteTime, muteBy, muteReason);
- handler.SendSysMessage(CypherStrings.YouDisableChat, nameLink, muteTime, muteReason);
+ target.SendSysMessage(CypherStrings.YourChatDisabled, muteTime, muteBy, muteReasonStr);
+ handler.SendSysMessage(CypherStrings.YouDisableChat, nameLink, muteTime, muteReasonStr);
}
else
{
- handler.SendSysMessage(CypherStrings.CommandDisableChatDelayed, nameLink, muteTime, muteReason);
+ handler.SendSysMessage(CypherStrings.CommandDisableChatDelayed, nameLink, muteTime, muteReasonStr);
}
return true;
@@ -1119,7 +1120,7 @@ namespace Game.Chat
}
[CommandNonGroup("neargrave", RBACPermissions.CommandNeargrave)]
- static bool HandleNearGraveCommand(CommandHandler handler, string teamArg)
+ static bool HandleNearGraveCommand(CommandHandler handler, [OptionalArg] string teamArg)
{
Team team;
if (teamArg.IsEmpty())
@@ -1890,7 +1891,7 @@ namespace Game.Chat
}
[CommandNonGroup("unfreeze", RBACPermissions.CommandUnfreeze)]
- static bool HandleUnFreezeCommand(CommandHandler handler, string targetNameArg)
+ static bool HandleUnFreezeCommand(CommandHandler handler, [OptionalArg] string targetNameArg)
{
string name = "";
Player player;
@@ -2267,7 +2268,7 @@ namespace Game.Chat
}
[Command("set", RBACPermissions.CommandAdditemset)]
- static bool HandleAddItemSetCommand(CommandHandler handler, uint itemSetId, string bonuses, string context)
+ static bool HandleAddItemSetCommand(CommandHandler handler, uint itemSetId, [OptionalArg] string bonuses, byte? context)
{
// prevent generation all items with itemset field value '0'
if (itemSetId == 0)
@@ -2290,8 +2291,8 @@ namespace Game.Chat
}
ItemContext itemContext = ItemContext.None;
- if (!context.IsEmpty())
- itemContext = context.ToEnum();
+ if (context.HasValue)
+ itemContext = (ItemContext)context;
Player player = handler.GetSession().GetPlayer();
Player playerTarget = handler.GetSelectedPlayer();
diff --git a/Source/Game/Chat/Commands/NPCCommands.cs b/Source/Game/Chat/Commands/NPCCommands.cs
index 507369293..5c6281d6c 100644
--- a/Source/Game/Chat/Commands/NPCCommands.cs
+++ b/Source/Game/Chat/Commands/NPCCommands.cs
@@ -283,7 +283,7 @@ namespace Game.Chat
}
[Command("say", RBACPermissions.CommandNpcSay)]
- static bool HandleNpcSayCommand(CommandHandler handler, string text)
+ static bool HandleNpcSayCommand(CommandHandler handler, Tail text)
{
if (text.IsEmpty())
return false;
@@ -298,7 +298,7 @@ namespace Game.Chat
creature.Say(text, Language.Universal);
// make some emotes
- switch (text.LastOrDefault())
+ switch (((string)text).LastOrDefault())
{
case '?':
creature.HandleEmoteCommand(Emote.OneshotQuestion);
@@ -480,7 +480,7 @@ namespace Game.Chat
}
[Command("textemote", RBACPermissions.CommandNpcTextemote)]
- static bool HandleNpcTextEmoteCommand(CommandHandler handler, string text)
+ static bool HandleNpcTextEmoteCommand(CommandHandler handler, Tail text)
{
Creature creature = handler.GetSelectedCreature();
if (!creature)
@@ -495,7 +495,7 @@ namespace Game.Chat
}
[Command("whisper", RBACPermissions.CommandNpcWhisper)]
- static bool HandleNpcWhisperCommand(CommandHandler handler, string recv, string text)
+ static bool HandleNpcWhisperCommand(CommandHandler handler, string recv, Tail text)
{
if (text.IsEmpty())
{
@@ -520,7 +520,7 @@ namespace Game.Chat
}
[Command("yell", RBACPermissions.CommandNpcYell)]
- static bool HandleNpcYellCommand(CommandHandler handler, string text)
+ static bool HandleNpcYellCommand(CommandHandler handler, Tail text)
{
if (text.IsEmpty())
return false;
@@ -625,7 +625,7 @@ namespace Game.Chat
}
[Command("item", RBACPermissions.CommandNpcAddItem)]
- static bool HandleNpcAddVendorItemCommand(CommandHandler handler, uint itemId, uint? mc, uint? it, uint? ec, string bonusListIds)
+ static bool HandleNpcAddVendorItemCommand(CommandHandler handler, uint itemId, uint? mc, uint? it, uint? ec, [OptionalArg] string bonusListIds)
{
if (itemId == 0)
{
@@ -740,7 +740,7 @@ namespace Game.Chat
}
[Command("temp", RBACPermissions.CommandNpcAddTemp)]
- static bool HandleNpcAddTempSpawnCommand(CommandHandler handler, string lootStr, uint id)
+ static bool HandleNpcAddTempSpawnCommand(CommandHandler handler, [OptionalArg] string lootStr, uint id)
{
bool loot = false;
if (!lootStr.IsEmpty())
diff --git a/Source/Game/Chat/Commands/TeleCommands.cs b/Source/Game/Chat/Commands/TeleCommands.cs
index e8a0faea8..1b894e060 100644
--- a/Source/Game/Chat/Commands/TeleCommands.cs
+++ b/Source/Game/Chat/Commands/TeleCommands.cs
@@ -333,14 +333,16 @@ namespace Game.Chat
}
[Command("name", RBACPermissions.CommandTeleName, true)]
- static bool HandleTeleNameNpcNameCommand(CommandHandler handler, PlayerIdentifier player, string name)
+ static bool HandleTeleNameNpcNameCommand(CommandHandler handler, PlayerIdentifier player, Tail name)
{
+ string normalizedName = name;
+
if (player == null)
return false;
- DB.World.EscapeString(ref name);
+ DB.World.EscapeString(ref normalizedName);
- SQLResult result = DB.World.Query($"SELECT c.position_x, c.position_y, c.position_z, c.orientation, c.map, ct.name FROM creature c INNER JOIN creature_template ct ON c.id = ct.entry WHERE ct.name LIKE '{name}'");
+ SQLResult result = DB.World.Query($"SELECT c.position_x, c.position_y, c.position_z, c.orientation, c.map, ct.name FROM creature c INNER JOIN creature_template ct ON c.id = ct.entry WHERE ct.name LIKE '{normalizedName}'");
if (result.IsEmpty())
{
handler.SendSysMessage(CypherStrings.CommandGocreatnotfound);
diff --git a/Source/Game/Chat/Hyperlink.cs b/Source/Game/Chat/Hyperlink.cs
index a1e904b10..075e48aa7 100644
--- a/Source/Game/Chat/Hyperlink.cs
+++ b/Source/Game/Chat/Hyperlink.cs
@@ -15,12 +15,7 @@
* along with this program. If not, see .
*/
-using Framework.Constants;
-using Framework.IO;
-using Game.DataStorage;
-using Game.Spells;
using System;
-using System.Collections.Generic;
namespace Game.Chat
{
@@ -39,7 +34,7 @@ namespace Game.Chat
return true;
}
- public static bool TryParse(out dynamic value, Type type, StringArguments args)
+ public static bool TryParse(out dynamic value, Type type, CommandArguments args)
{
value = default;
@@ -77,10 +72,10 @@ namespace Game.Chat
switch (type.Name)
{
case nameof(PlayerIdentifier):
- value = PlayerIdentifier.ParseFromString(args.NextString());
+ value = PlayerIdentifier.ParseFromString(args);
break;
case nameof(AccountIdentifier):
- value = AccountIdentifier.ParseFromString(args.NextString());
+ value = AccountIdentifier.ParseFromString(args);
break;
default:
return false;