/*************************************************************************** * Commands.cs * ------------------- * begin : May 1, 2002 * copyright : (C) The RunUO Software Team * email : info@runuo.com * * $Id$ * ***************************************************************************/ /*************************************************************************** * * 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 2 of the License, or * (at your option) any later version. * ***************************************************************************/ using System; using System.Collections.Generic; using Server.Network; namespace Server.Commands { public delegate void CommandEventHandler( CommandEventArgs e ); public class CommandEventArgs : EventArgs { private Mobile m_Mobile; private string m_Command, m_ArgString; private string[] m_Arguments; public Mobile Mobile => m_Mobile; public string Command => m_Command; public string ArgString => m_ArgString; public string[] Arguments => m_Arguments; public int Length => m_Arguments.Length; public string GetString( int index ) { if ( index < 0 || index >= m_Arguments.Length ) return ""; return m_Arguments[index]; } public int GetInt32( int index ) { if ( index < 0 || index >= m_Arguments.Length ) return 0; return Utility.ToInt32( m_Arguments[index] ); } public bool GetBoolean( int index ) { if ( index < 0 || index >= m_Arguments.Length ) return false; return Utility.ToBoolean( m_Arguments[index] ); } public double GetDouble( int index ) { if ( index < 0 || index >= m_Arguments.Length ) return 0.0; return Utility.ToDouble( m_Arguments[index] ); } public TimeSpan GetTimeSpan( int index ) { if ( index < 0 || index >= m_Arguments.Length ) return TimeSpan.Zero; return Utility.ToTimeSpan( m_Arguments[index] ); } public CommandEventArgs( Mobile mobile, string command, string argString, string[] arguments ) { m_Mobile = mobile; m_Command = command; m_ArgString = argString; m_Arguments = arguments; } } public class CommandEntry : IComparable { private string m_Command; private CommandEventHandler m_Handler; private AccessLevel m_AccessLevel; public string Command => m_Command; public CommandEventHandler Handler => m_Handler; public AccessLevel AccessLevel => m_AccessLevel; public CommandEntry( string command, CommandEventHandler handler, AccessLevel accessLevel ) { m_Command = command; m_Handler = handler; m_AccessLevel = accessLevel; } public int CompareTo( object obj ) { if ( obj == this ) return 0; if ( obj == null ) return 1; if ( !(obj is CommandEntry e) ) throw new ArgumentException(); return m_Command.CompareTo( e.m_Command ); } } public static class CommandSystem { private static string m_Prefix = "["; public static string Prefix { get => m_Prefix; set => m_Prefix = value; } public static string[] Split( string value ) { char[] array = value.ToCharArray(); List list = new List(); int start = 0; while ( start < array.Length ) { char c = array[start]; if ( c == '"' ) { ++start; int end = start; while ( end < array.Length ) { if ( array[end] != '"' || array[end - 1] == '\\' ) ++end; else break; } list.Add( value.Substring( start, end - start ) ); start = end + 2; } else if ( c != ' ' ) { int end = start; while ( end < array.Length ) { if ( array[end] != ' ' ) ++end; else break; } list.Add( value.Substring( start, end - start ) ); start = end + 1; } else { ++start; } } return list.ToArray(); } private static Dictionary m_Entries; public static Dictionary Entries => m_Entries; static CommandSystem() { m_Entries = new Dictionary( StringComparer.OrdinalIgnoreCase ); } public static void Register( string command, AccessLevel access, CommandEventHandler handler ) { m_Entries[command] = new CommandEntry( command, handler, access ); } private static AccessLevel m_BadCommandIngoreLevel = AccessLevel.Player; public static AccessLevel BadCommandIgnoreLevel{ get => m_BadCommandIngoreLevel; set => m_BadCommandIngoreLevel = value; } public static bool Handle( Mobile from, string text ) { return Handle( from, text, MessageType.Regular ); } public static bool Handle( Mobile from, string text, MessageType type ) { if ( text.StartsWith( m_Prefix ) || type == MessageType.Command ) { if ( type != MessageType.Command ) text = text.Substring( m_Prefix.Length ); int indexOf = text.IndexOf( ' ' ); string command; string[] args; string argString; if ( indexOf >= 0 ) { argString = text.Substring( indexOf + 1 ); command = text.Substring( 0, indexOf ); args = Split( argString ); } else { argString = ""; command = text.ToLower(); args = new string[0]; } m_Entries.TryGetValue( command, out CommandEntry entry ); if ( entry != null ) { if ( from.AccessLevel >= entry.AccessLevel ) { if ( entry.Handler != null ) { CommandEventArgs e = new CommandEventArgs( from, command, argString, args ); entry.Handler( e ); EventSink.InvokeCommand( e ); } } else { if ( from.AccessLevel <= m_BadCommandIngoreLevel ) return false; from.SendMessage( "You do not have access to that command." ); } } else { if ( from.AccessLevel <= m_BadCommandIngoreLevel ) return false; from.SendMessage( "That is not a valid command." ); } return true; } return false; } } }