internal SharedDelegate(MethodInfo info, SharedClass sharedClass, Type DelegateType, int DelegateId, Delegate Delegate, int MethodId) { this.sharedMethod = new SharedMethod(info, sharedClass, true, DelegateId); this.DelegateType = DelegateType; this.Delegate = Delegate; this.sharedMethod.MethodId = MethodId; }
public void Dispose() { Name = null; ArgumentTypes = null; ReturnType = null; sharedClass = null; }
internal SharedMethod(MethodInfo info, SharedClass sharedClass, bool isDelegate = false, int DelegateId = 0) { this.Name = info.Name; this.DelegateIndex = new SortedList <int, SharedDelegateInfo>(); this.Delegates = new SortedList <int, SharedDelegate>(); ParameterInfo[] parameters = info.GetParameters(); List <Type> types = new List <Type>(); for (int i = 0; i < parameters.Length; i++) { types.Add(parameters[i].ParameterType); if (parameters[i].ParameterType.BaseType != null) { if (parameters[i].ParameterType.BaseType.FullName == "System.MulticastDelegate") { DelegateIndex.Add(i, new SharedDelegateInfo() { isUnchecked = (parameters[i].GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length > 0), UsePacketQueue = (parameters[i].GetCustomAttributes(typeof(PacketQueueAttribute), false).Length > 0), UseUDP = (parameters[i].GetCustomAttributes(typeof(UdpMethodAttribute), false).Length > 0) }); } } } this.ArgumentTypes = types.ToArray(); this.ReturnType = info.ReturnType; this.Unchecked = (info.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length > 0); this.usePacketQueue = (info.GetCustomAttributes(typeof(PacketQueueAttribute), false).Length > 0); this.useUdp = (info.GetCustomAttributes(typeof(UdpMethodAttribute), false).Length > 0); object[] tempAttr = info.GetCustomAttributes(typeof(RemoteExecutionAttribute), false); if (tempAttr.Length > 0) { TimeOutLength = (tempAttr[0] as RemoteExecutionAttribute).TimeOut; TimeOutValue = (tempAttr[0] as RemoteExecutionAttribute).TimeOutValue; } types.Clear(); types = null; this.CanReturn = info.ReturnType.FullName != "System.Void"; this.sharedClass = sharedClass; this.isDelegate = isDelegate; this.DelegateId = DelegateId; }
internal SharedMethod(MethodInfo info, SharedClass sharedClass, bool isDelegate = false, int DelegateId = 0) { this.Name = info.Name; this.DelegateIndex = new SortedList<int, SharedDelegateInfo>(); this.Delegates = new SortedList<int, SharedDelegate>(); ParameterInfo[] parameters = info.GetParameters(); List<Type> types = new List<Type>(); for (int i = 0; i < parameters.Length; i++) { types.Add(parameters[i].ParameterType); if (parameters[i].ParameterType.BaseType != null) { if (parameters[i].ParameterType.BaseType.FullName == "System.MulticastDelegate") { DelegateIndex.Add(i, new SharedDelegateInfo() { isUnchecked = (parameters[i].GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length > 0), UsePacketQueue = (parameters[i].GetCustomAttributes(typeof(PacketQueueAttribute), false).Length > 0), UseUDP = (parameters[i].GetCustomAttributes(typeof(UdpMethodAttribute), false).Length > 0), NoWaitingTime = (parameters[i].GetCustomAttributes(typeof(NoWaitMethodAttribute), false).Length > 0) }); } } } this.ArgumentTypes = types.ToArray(); this.ReturnType = info.ReturnType; this.Unchecked = (info.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length > 0); this.usePacketQueue = (info.GetCustomAttributes(typeof(PacketQueueAttribute), false).Length > 0); this.useUdp = (info.GetCustomAttributes(typeof(UdpMethodAttribute), false).Length > 0); this.NoWaitingTime = (info.GetCustomAttributes(typeof(NoWaitMethodAttribute), false).Length > 0); types.Clear(); types = null; this.CanReturn = info.ReturnType.FullName != "System.Void"; this.sharedClass = sharedClass; this.isDelegate = isDelegate; this.DelegateId = DelegateId; }
/// <summary> /// Get the shared class from the remote client to call methods at the remote client /// </summary> /// <param name="classType">The main Type to use</param> /// <param name="InterfacePrototype">This interface should contain all the methods used in the ClassType</param> /// <returns>return Shared Class</returns> public InterfacePrototype CreateDynamicClass <InterfacePrototype>(SharedClass sharedClass) { lock (Locky) { Type prototype = typeof(InterfacePrototype); if (!prototype.IsInterface || !prototype.IsPublic) { throw new Exception("InterfacePrototype must be a interface and public"); } if (!TypeCache.ContainsKey(prototype.FullName)) { TypeBuilder typeBuilder = modBuilder.DefineType("dyn_" + prototype.Name, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(object), new Type[] { prototype }); //add our RootSocket info, I did on purpose "$" so u can't directly access this variable FieldBuilder fb = typeBuilder.DefineField("$haredClass", typeof(SharedClass), FieldAttributes.Public); DuplicateMethods(typeBuilder, prototype, fb, sharedClass); CreateConstructor(typeBuilder, fb); CreateDeconstructor(typeBuilder, fb); Type InitType = typeBuilder.CreateType(); TypeCache.Add(prototype.FullName, InitType); return((InterfacePrototype)InitType.GetConstructor(new Type[] { typeof(SharedClass) }).Invoke(new object[] { sharedClass })); } else { return((InterfacePrototype)TypeCache[prototype.FullName].GetConstructor(new Type[] { typeof(SharedClass) }).Invoke(new object[] { sharedClass })); } } }
private void DuplicateMethods(TypeBuilder typeBuilder, Type target, FieldBuilder fb, SharedClass sharedClass) { foreach (MethodInfo m in target.GetMethods()) { /*if ((m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && * m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) && * m.Name != "Dispose") * { * continue; * }*/ Type[] ArgumentTypes = GetParameterTypes(m.GetParameters()); MethodBuilder builder = typeBuilder.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, m.CallingConvention, m.ReturnType, ArgumentTypes); typeBuilder.DefineMethodOverride(builder, m); //builder.CreateMethodBody(null, 0); ILGenerator gen = builder.GetILGenerator(); MethodInfo SharedCall = typeof(SharedClass).GetMethod("Invoke", new Type[] { typeof(int), typeof(object[]) }); SharedMethod sharedMethod = sharedClass.GetMethod(m.Name, ArgumentTypes); LocalBuilder lb = gen.DeclareLocal(typeof(object[])); if (sharedMethod == null) { throw new Exception("Missing a method \"" + m.Name + "\" check your shared class!"); } //load $haredClass gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, fb); gen.Emit(OpCodes.Ldc_I4, sharedMethod.MethodId); //gen.Emit(OpCodes.Ldstr, m.Name); //init local array gen.Emit(OpCodes.Ldc_I4, ArgumentTypes.Length); gen.Emit(OpCodes.Newarr, typeof(object)); gen.Emit(OpCodes.Stloc_0); for (int i = 0; i < ArgumentTypes.Length; i++) { gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (ArgumentTypes[i].IsByRef) { //remove & at the end since ref/out adds & at the end of the argument ArgumentTypes[i] = Type.GetType(ArgumentTypes[i].FullName.Substring(0, ArgumentTypes[i].FullName.Length - 1)); } gen.Emit(OpCodes.Box, ArgumentTypes[i]); gen.Emit(OpCodes.Stelem_Ref); } gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Callvirt, SharedCall); bool isInt = m.ReturnType.IsAssignableFrom(typeof(System.Int32)) || m.ReturnType.IsAssignableFrom(typeof(System.UInt32)) || m.ReturnType.IsAssignableFrom(typeof(System.Boolean)) || m.ReturnType.IsAssignableFrom(typeof(System.Int64)) || m.ReturnType.IsAssignableFrom(typeof(System.UInt64)); if (m.ReturnType.FullName != "System.Void" && !isInt) { gen.Emit(OpCodes.Box, m.ReturnType); } else if (m.ReturnType.FullName == "System.Void") //no return { gen.Emit(OpCodes.Pop); } else if (isInt) { gen.Emit(OpCodes.Unbox, m.ReturnType); gen.Emit(OpCodes.Ldobj, m.ReturnType); } gen.Emit(OpCodes.Ret); } }
public object onRequest(AClient connection, MsgGetSharedClass request) { ReturnResult result = new ReturnResult(null, false); lock(connection.SharingClasses) { try { if (connection.SharingClasses.ContainsKey(request.ClassName)) { SharedClass localSharedClass = connection.SharingClasses[request.ClassName]; if (localSharedClass.RemoteInitialize) { bool FoundConstructor = false; if (request.ArgObjects.Length > 0) { //lets check if there is a constructor with these arguments for (int i = 0; i < localSharedClass.ConstructorTypes.Count; i++) { if (localSharedClass.ConstructorTypes[i].Length == request.ArgObjects.Length) { bool CorrectArgs = true; for (int j = 0; j < request.ArgObjects.Length; j++) { if (localSharedClass.ConstructorTypes[i][j] != request.ArgObjects[j].GetType() && localSharedClass.ConstructorTypes[i][j] != request.ArgObjects[j].GetType().BaseType) { CorrectArgs = false; break; } } if (CorrectArgs) { FoundConstructor = true; break; } } } if (!FoundConstructor) return null; } } SharedClass sClass = new SharedClass(localSharedClass.BaseClassType, connection, localSharedClass.RemoteInitialize, localSharedClass.BaseClassTypeArgs); sClass.InitializedClass = Activator.CreateInstance(sClass.BaseClassType, localSharedClass.RemoteInitialize ? request.ArgObjects : sClass.BaseClassTypeArgs); Random rnd = new Random(DateTime.Now.Millisecond); int RandomId = rnd.Next(); while (connection.RemoteSharedClasses.ContainsKey(RandomId)) RandomId = rnd.Next(); sClass.SharedId = RandomId; connection.RemoteSharedClasses.Add(RandomId, sClass); result.ReturnValue = sClass; return result; } } catch (Exception ex) { result.ExceptionOccured = true; result.exceptionMessage = ex.InnerException != null ? ex.InnerException.Message : ex.Message; } } return result; }