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(); } }
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); } }
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); }
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); } }