public object Invoke(int MethodId, params object[] args) { SharedMethod method = GetMethod(MethodId); lock (method.InvokeLocky) { ReturnResult ret = method.Invoke(args) as ReturnResult; if (ret != null) { if (ret.ExceptionOccured) { throw new Exception(ret.exceptionMessage); } return(ret.ReturnValue); } return(null); } throw new Exception("Method not found"); }
public object onRequest(AClient connection, PayloadReader pr) { ReturnResult result = new ReturnResult(null, false); bool isDelegate = false; bool ReadFullHeader = false; try { int SharedClassId = pr.ReadInteger(); int MethodId = pr.ReadInteger(); isDelegate = pr.ReadByte() == 1; int DelegateId = isDelegate ? pr.ReadInteger() : 0; int DelegateClassId = isDelegate ? pr.ReadInteger() : 0; ReadFullHeader = true; if (connection.RemoteSharedClasses.ContainsKey(SharedClassId) || (isDelegate && connection.LocalSharedClasses.ContainsKey(DelegateClassId))) { SharedClass sClass = isDelegate ? connection.LocalSharedClasses[SharedClassId] : connection.RemoteSharedClasses[SharedClassId]; SharedMethod sharedMethod = sClass.GetMethod(MethodId); if (sharedMethod != null) { List<object> args = new List<object>(); List<Type> types = new List<Type>(); SortedList<int, SharedDelegate> SharedDelegates = new SortedList<int, SharedDelegate>(); SmartSerializer serializer = new SmartSerializer(); lock(sharedMethod.Delegates) { if(sharedMethod.Delegates.ContainsKey(DelegateId)) { for (int i = 0; i < sharedMethod.Delegates[DelegateId].sharedMethod.ArgumentTypes.Length; i++) { args.Add(serializer.Deserialize(pr.ReadBytes(pr.ReadInteger()))); } } else { for (int i = 0; i < sharedMethod.ArgumentTypes.Length; i++) { args.Add(serializer.Deserialize(pr.ReadBytes(pr.ReadInteger()))); } } } if (!isDelegate) //atm no support yet for delegate inside another delegate { for (int i = 0; i < sharedMethod.DelegateIndex.Count; i++) { if (pr.ReadByte() == 1) { SharedDelegate del = pr.ReadObject<SharedDelegate>(); del.sharedMethod.sharedClass = sClass; args[sharedMethod.DelegateIndex.Keys[i]] = DynamicDelegateCreator.CreateDelegate(del); SharedDelegates.Add(del.sharedMethod.DelegateId, del); } } } if (isDelegate) { //only show the result and not the actual ReturnResult type return sharedMethod.Delegates[DelegateId].Delegate.DynamicInvoke(args.ToArray()); } else { MethodInfo m = sClass.InitializedClass.GetType().GetMethod(sharedMethod.Name, sharedMethod.ArgumentTypes); if (m.GetCustomAttributes(typeof(RemoteExecutionAttribute), false).Length == 0 && m.GetCustomAttributes(typeof(UncheckedRemoteExecutionAttribute), false).Length == 0) { return null; } result.ReturnValue = m.Invoke(sClass.InitializedClass, args.ToArray()); } } } } catch (Exception ex) { if (isDelegate && ReadFullHeader) throw ex; result.exceptionMessage = ex.InnerException != null ? ex.InnerException.Message : ex.Message; result.ExceptionOccured = true; } return result; }
private void _Invoke(ref object RetObject, params object[] args) { if (args.Length < ArgumentTypes.Length) //check if a argument is using "params x[] args" { throw new Exception("missing arguments"); } List <int> usedDelegates = new List <int>(); PayloadWriter pw = new PayloadWriter(); SmartSerializer serializer = new SmartSerializer(); for (int i = 0; i < args.Length; i++) { object obj = ArgumentTypes[i].IsByRef ? null : args[i]; if (DelegateIndex.ContainsKey(i)) { obj = null; } byte[] SerializedObj = serializer.Serialize(obj); pw.WriteInteger(SerializedObj.Length); pw.WriteBytes(SerializedObj); } for (int i = 0; i < DelegateIndex.Count; i++) { Delegate del = args[DelegateIndex.Keys[i]] as Delegate; if (del != null) { if (del.Method == null) { throw new Exception("Target delegate is NULL"); } int id = rnd.Next(); while (Delegates.ContainsKey(id)) { id = rnd.Next(); } pw.WriteBool(true); SharedDelegate sharedDel = new SharedDelegate(del.Method, sharedClass, del.GetType(), id, del, this.MethodId); sharedDel.sharedMethod.Unchecked = this.Unchecked; //DelegateIndex.Values[i].isUnchecked; sharedDel.sharedMethod.usePacketQueue = this.usePacketQueue; //DelegateIndex.Values[i].UsePacketQueue; sharedDel.sharedMethod.useUdp = this.useUdp; //DelegateIndex.Values[i].UseUDP; pw.WriteObject(sharedDel); if (!isDelegate) { Delegates.Add(id, sharedDel); } continue; } pw.WriteBool(false); } try { if (Unchecked || useUdp) { //just execute the method and don't wait for response sharedClass.Client.Send(new MsgExecuteMethod(0, pw.ToByteArray(), false, sharedClass.SharedId, MethodId, this.DelegateId, this.sharedClass.SharedId)); } else { SyncObject syncObject = null; Random rnd = new Random(); int RequestId = rnd.Next(); lock (sharedClass.Client.Requests) { while (sharedClass.Client.Requests.ContainsKey(RequestId)) { RequestId = rnd.Next(); } syncObject = new SyncObject(sharedClass.Client); sharedClass.Client.Requests.Add(RequestId, syncObject); sharedClass.Client.Send(new MsgExecuteMethod(RequestId, pw.ToByteArray(), true, sharedClass.SharedId, MethodId, this.DelegateId, this.sharedClass.SharedId)); } RetObject = syncObject.Wait <ReturnResult>(null, TimeOutLength); if (syncObject.TimedOut) { //copying the object in memory, maybe a strange way todo it but it works RetObject = new ReturnResult(serializer.Deserialize(serializer.Serialize(this.TimeOutValue)), false); } } } catch { //client most likely disconnected and was unable to send the message RetObject = null; } /*if (callback != null) * { * sharedClass.connection.BeginSendRequest(pw, callback, true, this.usePacketQueue); * } * else * { * if (Unchecked || useUdp) * { * //just don't wait till we received something back since it's a VOID anyway * sharedClass.connection.BeginSendRequest(pw, (object obj) => { }, false, this.usePacketQueue); * } * else * { * RetObject = sharedClass.connection.SendRequest(pw, this.usePacketQueue); * } * }*/ serializer = null; }
public MsgExecuteMethodResponse(int RequestId, ReturnResult result) : base() { this.RequestId = RequestId; this.result = result; }
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; }
public MsgGetSharedClassResponse(int RequestId, ReturnResult Result) : base() { this.RequestId = RequestId; this.Result = Result; }