예제 #1
0
파일: Devcom.cs 프로젝트: snowfox0x/Devcom
        /// <summary>
        /// Executes a command string under the specified context.
        /// </summary>
        /// <param name="context">The context under which to execute the command.</param>
        /// <param name="command">The command to execute.</param>
        public static void Submit(Context context, string command)
        {
            if (!_loaded) return;

            // Set the context to default if null was passed
            context = context ?? Context.Default;

            if (SystemConvars.EchoInput)
            {
                context.Notify("> " + command);
            }

            // Don't interpret empty commands
            if (String.IsNullOrEmpty(command)) return;

            // Cut off spaces from both ends
            command = command.Trim();

            foreach (var cmdstr in command.Split(new[] { '|', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(s => s.Trim()))
            {
                // Split up the line into arguments
                var parts = cmdstr.ParseParams().ToArray();
                if (!parts.Any()) continue;

                // The first index will be the command name
                var first = parts.First().ToLower();
                
                // Check if it's a root marker
                if (first == "$")
                {
                    context.Category = "";
                    continue;
                }

                // Check for root marker at the start of command name
                bool root = false;
                if (first.StartsWith("$"))
                {
                    root = true;
                    first = first.Substring(1);
                }

                // Get the fully-qualified name, taking into account root markers and current category
                string qname = root ? first : (context.Category.Length > 0 ? context.Category + "." : "") + first;

                // Make sure the command exists
                Command cmd;
                if (!Commands.TryGetValue(qname, out cmd))
                {
                    context.PostCommandNotFound(qname);
                    continue;
                }

                if (parts.Length > 1)
                {
                    for (int i = 1; i < parts.Length; i++)
                    {
                        parts[i] = Regex.Replace(parts[i], @":(?<name>\S+):",
                            m => Util.GetConvarValue(m.Groups["name"].Value, context.Category),
                            RegexOptions.ExplicitCapture);
                    }
                }

                // Run the command
                cmd.Run(context, parts.Where((s, i) => i > 0).ToArray());
            }
        }
예제 #2
0
파일: Command.cs 프로젝트: snowfox0x/Devcom
        internal bool Run(Context context, params string[] args)
        {
            var currentContextType = context.GetType();

            // Check context type compatability
            if ((!currentContextType.IsSubclassOf(_contextType) && currentContextType != _contextType) || !ContextFilter.Test(currentContextType, Filter))
            {
                context.PostCommandNotFound(QualifiedName);
                return false;
            }

            int argc = args.Length;
            int paramc = _paramList.Length - 1;
            try
            {
                if ((_hasParamsArgument && argc < paramc) || (argc < paramc - _numOptionalParams) || (!_hasParamsArgument && argc > paramc))
                {
                    context.Notify("Parameter count mismatch.");
                    return false;
                }

                var boxed = Enumerable.Repeat(Type.Missing, paramc).ToArray();

                // Convert parameters to the proper types
                for (int i = 0; i < paramc; i++)
                {
                    boxed[i] = Util.ChangeType(args[i], _paramList[(i >= paramc ? paramc - 1 : i) + 1].ParameterType);
                }

                var argsFormatted = new List<object> { context };

                // Add all arguments except for any marked as 'params'
                argsFormatted.AddRange(boxed.Take(_hasParamsArgument ? paramc - 1 : paramc));

                // Insert params argument as an array (it needs to be represented as a single object)
                if (_hasParamsArgument)
                {
                    argsFormatted.Add(args.Where((o, i) => i >= paramc - 1).ToArray());
                }

                // Call the method with our parameters
                _method.Invoke(null, argsFormatted.ToArray());
            }
            catch(Exception ex)
            {
                if (SystemConvars.Throws)
                {
                    throw;
                }
                context.Notify("Error: " + ex);
                return false;
            }
            return true;
        }