Пример #1
0
        private object RunInternal(MethodOverloads methodOverloads, object[] rawParams)
        {
            // TODO: Security
            FileIOPermission phoenixLauncherFile = new FileIOPermission(FileIOPermissionAccess.AllAccess, System.IO.Path.Combine(Core.Directory, "PhoenixLauncher.xml"));
            phoenixLauncherFile.Deny();

            // First create ParameterData array
            ParameterData[] parameters = new ParameterData[rawParams.Length];
            for (int i = 0; i < rawParams.Length; i++) {
                parameters[i] = new ParameterData(rawParams[i]);
            }

            // Get valid overloads (array is never empty)
            Method[] methods = methodOverloads.FindOverloads(parameters);

            Exception exception = null;

            foreach (Method m in methods) {
                ExecutionInfo info = new ExecutionInfo(m);

                ExecutionAttribute[] execAttributes = (ExecutionAttribute[])m.MethodInfo.GetCustomAttributes(typeof(ExecutionAttribute), false);

                try {
                    // Call all Execution attributes
                    for (int i = 0; i < execAttributes.Length; i++) {
                        execAttributes[i].Starting(m);
                    }

                    // Add execution to running list
                    lock (syncRoot) {
                        if (runningExecutions.Count >= Executions.MaxExecutions) {
                            throw new RuntimeException("Executions limit exceeded.");
                        }

                        RuntimeCore.AddAssemblyObject(info, this);
                        runningExecutions.Add(info);

                        try {
                            // Raise Started event
                            executionStarted.Invoke(this, new ExecutionsChangedEventArgs(info));
                        }
                        catch (Exception e) {
                            Core.ShowMessageBoxAsync("Unhandled exception in Executions.ExecutionStarted event handler.\r\nMessage: " + e.Message, "Warning");
                        }
                    }

                    // Init thread-dependent classes
                    if (!threadInitialized) {
                        ScriptErrorException.ThreadInit();
                        WorldData.World.ThreadInit();
                        Journal.ThreadInit();
                        threadInitialized = true;
                    }

                    // Invoke
                    try {
                        return m.Invoke(parameters);
                    }
                    catch (System.Reflection.TargetInvocationException e) {
                        // Im interested only in exception thrown by code
                        throw e.InnerException;
                    }
                }
                catch (ParameterException e) {
                    exception = e;
                }
                catch (ExecutionBlockedException e) {
                    exception = e;
                }
                finally {
                    // Remove execution from running list
                    lock (syncRoot) {
                        runningExecutions.Remove(info);
                        RuntimeCore.RemoveAssemblyObject(info);

                        try {
                            // Raise Finished event
                            executionFinished.Invoke(this, new ExecutionsChangedEventArgs(info));
                        }
                        catch (Exception e) {
                            Core.ShowMessageBoxAsync("Unhandled exception in Executions.ExecutionFinished event handler.\r\nMessage: " + e.Message, "Warning");
                        }
                    }

                    // Call all Execution attributes
                    for (int i = 0; i < execAttributes.Length; i++) {
                        execAttributes[i].Finished(m);
                    }
                }
            }

            if (exception != null) {
                throw exception;
            }
            else {
                throw new InternalErrorException();
            }
        }
Пример #2
0
        public object ConvertTo(Type targetType, TypeClass targetClass)
        {
            try
            {
                // Check null value
                if (this.IsNull)
                {
                    if (!targetType.IsValueType)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new ParameterException("Cannot convert null to ValueType.");
                    }
                }

                // Check if it isn't already in appropriate type
                if (targetType == this.Source.GetType())
                {
                    return(this.Source);
                }

                // If string is requested return already known value
                if (targetType == typeof(String))
                {
                    return(this.String);
                }

                // Convert numbers
                if (targetClass == TypeClass.Number)
                {
                    if (this.String.Length > 0)
                    {
                        // Try to resolve alias
                        ParameterData aliasData = null;

                        if (targetType == typeof(uint) || targetType == typeof(int) || targetType == typeof(Serial))
                        {
                            if (Aliases.ObjectExists(this.String))
                            {
                                aliasData = new ParameterData(Aliases.GetObject(this.String));
                            }
                        }

                        if (aliasData != null)
                        {
                            return(aliasData.ConvertTo(targetType, targetClass));
                        }
                    }

                    // If requested type is one of built-in use implemented converter
                    if (targetType.IsPrimitive)
                    {
                        return(Convert.ChangeType(this.Number, targetType));
                    }
                    else if (targetType == typeof(Serial))
                    {
                        return((Serial)(uint)this.Number);
                    }
                    else if (targetType == typeof(Graphic))
                    {
                        return((Graphic)(ushort)this.Number);
                    }
                    else if (targetType == typeof(UOColor))
                    {
                        return((UOColor)(ushort)this.Number);
                    }
                    else
                    {
                        throw new InternalErrorException("Unknown numeric type requested.");
                    }
                }

                // Unimplemented type
                if (targetClass == TypeClass.Object)
                {
                    // Try enum
                    if (targetType.IsEnum)
                    {
                        try
                        {
                            return(Enum.Parse(targetType, this.String, true));
                        }
                        catch { }
                    }

                    // Try IConvertible
                    if (this.Source is IConvertible)
                    {
                        try
                        {
                            return(((IConvertible)this.Source).ToType(targetType, null));
                        }
                        catch { }
                    }

                    // Try to find operators
                    List <MethodInfo> methods = new List <MethodInfo>();
                    methods.AddRange(targetType.GetMethods(BindingFlags.Public | BindingFlags.Static));
                    methods.AddRange(this.Source.GetType().GetMethods(BindingFlags.Public | BindingFlags.Static));
                    for (int i = 0; i < methods.Count; i++)
                    {
                        try
                        {
                            if (methods[i].Name == "op_Implicit" || methods[i].Name == "op_Explicit")
                            {
                                if (methods[i].ReturnType == targetType)
                                {
                                    ParameterInfo[] parameters = methods[i].GetParameters();
                                    if (parameters.Length == 1 && parameters[0].ParameterType == this.Source.GetType())
                                    {
                                        return(methods[i].Invoke(null, new object[] { this.Source }));
                                    }
                                }
                            }
                        }
                        catch { }
                    }

                    // Try to find Parse function
                    MethodInfo parseMethod = targetType.GetMethod("Parse", new Type[] { typeof(String) });
                    if (parseMethod != null)
                    {
                        try
                        {
                            return(parseMethod.Invoke(null, new object[] { this.String }));
                        }
                        catch { }
                    }

                    throw new ParameterException("No suitable convert method found.");
                }
                else
                {
                    throw new InternalErrorException("Invalid targetClass specified.");
                }
            }
            catch (Exception e)
            {
                string valueString = this.Source != null ? this.String : "null";
                if (valueString.Contains(" "))
                {
                    valueString = "\"" + valueString + "\"";
                }

                throw new ParameterException("Unable to convert " + valueString + " to " + targetType.ToString(), e);
            }
        }
Пример #3
0
        public object Invoke(ParameterData[] parametersData)
        {
            if (parametersData.Length < minParamCount || parametersData.Length > maxParamCount)
                throw new ParameterException("Invalid number of paramters.");

            // Parameters in exact types passed to Invoke method
            object[] valuesArray = new object[parameters.Length];

            for (int i = 0; i < parameters.Length; i++)
            {
                if (i < parametersData.Length)
                {
                    if (parametersData.Length < parameters.Length - 1)
                    {
                        valuesArray[i] = parametersData[i].ConvertTo(parameters[i]);
                    }
                    else
                    {
                        if (parameters[i].IsParamArray)
                        {
                            Debug.Assert(i == parameters.Length - 1);

                            int variableArgumentsCount = parametersData.Length - i;

                            Type argumentsType = parameters[i].Type.GetElementType();
                            TypeClass argumentsClass = TypeHelper.GetTypeClass(argumentsType);

                            IList variableArgs = Array.CreateInstance(argumentsType, variableArgumentsCount);

                            for (int vi = 0; vi < variableArgumentsCount; vi++)
                            {
                                variableArgs[vi] = parametersData[i + vi].ConvertTo(argumentsType, argumentsClass);
                            }

                            valuesArray[i] = variableArgs;
                        }
                        else
                        {
                            valuesArray[i] = parametersData[i].ConvertTo(parameters[i]);
                        }
                    }
                }
                else
                {
                    // Parameter is not specified
                    if (parameters[i].IsParamArray)
                    {
                        valuesArray[i] = Array.CreateInstance(parameters[i].Type.GetElementType(), 0);
                    }
                    else
                    {
                        Debug.Assert(parameters[i].IsOptional, "Parameter is not optional. Internal error.");
                        valuesArray[i] = Missing.Value;
                    }
                }
            }

            return method.Invoke(target, valuesArray);
        }
Пример #4
0
        public object ConvertTo(Type targetType, TypeClass targetClass)
        {
            try
            {
                // Check null value
                if (this.IsNull)
                {
                    if (!targetType.IsValueType)
                        return null;
                    else
                        throw new ParameterException("Cannot convert null to ValueType.");
                }

                // Check if it isn't already in appropriate type
                if (targetType == this.Source.GetType())
                {
                    return this.Source;
                }

                // If string is requested return already known value
                if (targetType == typeof(String))
                {
                    return this.String;
                }

                // Convert numbers
                if (targetClass == TypeClass.Number)
                {
                    if (this.String.Length > 0)
                    {
                        // Try to resolve alias
                        ParameterData aliasData = null;

                        if (targetType == typeof(uint) || targetType == typeof(int) || targetType == typeof(Serial))
                        {
                            if (Aliases.ObjectExists(this.String))
                            {
                                aliasData = new ParameterData(Aliases.GetObject(this.String));
                            }
                        }

                        if (aliasData != null)
                        {
                            return aliasData.ConvertTo(targetType, targetClass);
                        }
                    }

                    // If requested type is one of built-in use implemented converter
                    if (targetType.IsPrimitive)
                    {
                        return Convert.ChangeType(this.Number, targetType);
                    }
                    else if (targetType == typeof(Serial))
                    {
                        return (Serial)(uint)this.Number;
                    }
                    else if (targetType == typeof(Graphic))
                    {
                        return (Graphic)(ushort)this.Number;
                    }
                    else if (targetType == typeof(UOColor))
                    {
                        return (UOColor)(ushort)this.Number;
                    }
                    else
                    {
                        throw new InternalErrorException("Unknown numeric type requested.");
                    }
                }

                // Unimplemented type
                if (targetClass == TypeClass.Object)
                {
                    // Try enum
                    if (targetType.IsEnum)
                    {
                        try
                        {
                            return Enum.Parse(targetType, this.String, true);
                        }
                        catch { }
                    }

                    // Try IConvertible
                    if (this.Source is IConvertible)
                    {
                        try
                        {
                            return ((IConvertible)this.Source).ToType(targetType, null);
                        }
                        catch { }
                    }

                    // Try to find operators
                    List<MethodInfo> methods = new List<MethodInfo>();
                    methods.AddRange(targetType.GetMethods(BindingFlags.Public | BindingFlags.Static));
                    methods.AddRange(this.Source.GetType().GetMethods(BindingFlags.Public | BindingFlags.Static));
                    for (int i = 0; i < methods.Count; i++)
                    {
                        try
                        {
                            if (methods[i].Name == "op_Implicit" || methods[i].Name == "op_Explicit")
                            {
                                if (methods[i].ReturnType == targetType)
                                {
                                    ParameterInfo[] parameters = methods[i].GetParameters();
                                    if (parameters.Length == 1 && parameters[0].ParameterType == this.Source.GetType())
                                    {
                                        return methods[i].Invoke(null, new object[] { this.Source });
                                    }
                                }
                            }
                        }
                        catch { }
                    }

                    // Try to find Parse function
                    MethodInfo parseMethod = targetType.GetMethod("Parse", new Type[] { typeof(String) });
                    if (parseMethod != null)
                    {
                        try
                        {
                            return parseMethod.Invoke(null, new object[] { this.String });
                        }
                        catch { }
                    }

                    throw new ParameterException("No suitable convert method found.");
                }
                else
                {
                    throw new InternalErrorException("Invalid targetClass specified.");
                }
            }
            catch (Exception e)
            {
                string valueString = this.Source != null ? this.String : "null";
                if (valueString.Contains(" "))
                    valueString = "\"" + valueString + "\"";

                throw new ParameterException("Unable to convert " + valueString + " to " + targetType.ToString(), e);
            }
        }