Beispiel #1
0
        public object ConvertBackToObject(object CurrentObject, object[] Parameters)
        {
            MDLog.Trace(LOG_CAT, $"MDCommandReplicator converting back ({MDStatics.GetParametersAsString(Parameters)})");

            if (Parameters.Length == 1 && Parameters[0] == null)
            {
                return(null);
            }

            T obj;

            if (CurrentObject != null)
            {
                // Replace values in existing object
                obj = (T)CurrentObject;
            }
            else
            {
                // Return a new object
                obj = (T)Activator.CreateInstance(typeof(T));
            }

            for (int i = 0; i < Parameters.Length; i++)
            {
                // Get the length of the data
                int length = Convert.ToInt32(Parameters[i].ToString());

                // Extract parameters and apply to the command replicator
                object[] converterParams = Parameters.SubArray(i + 1, i + length);
                obj.MDProcessCommand(converterParams);
                i += length;
            }

            return((T)obj);
        }
        /// /// <summary>
        /// Invoke the method with the given number on the node
        /// </summary>
        /// <param name="MethodNumber">The method number to invoke</param>
        /// <param name="Parameters">Parameters</param>
        /// <returns>True if invoked, false if not found</returns>
        public static bool Invoke(this Node Instance, int MethodNumber, params object[] Parameters)
        {
            MethodInfo Info = MDStatics.GetMethodInfo(Instance, MethodNumber);

            if (Info != null)
            {
                MDLog.Trace(LOG_CAT, $"Invoking {Info.Name} with parameters {MDStatics.GetParametersAsString(Parameters)}");
                Info.Invoke(Instance, Parameters);
                return(true);
            }

            MDLog.Trace(LOG_CAT, $"Failed to invoke method number {MethodNumber} with parameters {MDStatics.GetParametersAsString(Parameters)}");
            return(false);
        }
Beispiel #3
0
        /// <summary>
        /// Apply the buffer to a member if it exists
        /// </summary>
        /// <param name="ID">The ID to check the buffer for</param>
        /// <param name="Member">The member to apply this buffer to</param>
        public void CheckBuffer(uint ID, MDReplicatedMember Member)
        {
            if (!ClockedValueBuffer.ContainsKey(ID))
            {
                return;
            }

            Dictionary <uint, object[]> buffer = GetBufferForId(ID);

            foreach (uint tick in buffer.Keys)
            {
                object[] value = buffer[tick];
                MDLog.Trace(LOG_CAT, $"Updating value to {MDStatics.GetParametersAsString(value)} for {ID} on tick {tick}");
                Member.SetValues(tick, value);
            }

            buffer.Clear();
            ClockedValueBuffer.Remove(ID);
        }
Beispiel #4
0
        public object ConvertBackToObject(object CurrentObject, object[] Parameters)
        {
            ExtractMembers();
            MDLog.Trace(LOG_CAT, $"MDCustomClass converting back ({MDStatics.GetParametersAsString(Parameters)})");

            if (Parameters.Length == 1 && Parameters[0] == null)
            {
                return(null);
            }

            T obj;

            if (CurrentObject != null)
            {
                // Replace values in existing object
                obj = (T)CurrentObject;
            }
            else
            {
                // Return a new object
                obj = (T)Activator.CreateInstance(typeof(T));
            }

            for (int i = 0; i < Parameters.Length; i++)
            {
                // key0 = index, key1 = length
                object[] keys   = Parameters[i].ToString().Split(SEPARATOR);
                int      index  = Convert.ToInt32(keys[0].ToString());
                int      length = Convert.ToInt32(keys[1].ToString());

                // Extract parameters and use data converter
                object[] converterParams = Parameters.SubArray(i + 1, i + length);
                object   currentValue    = Members[index].GetValue(obj);
                object   convertedValue  = DataConverters[index].ConvertBackToObject(currentValue, converterParams);

                // Set the value and increase i based on length of data
                Members[index].SetValue(obj, convertedValue);
                i += length;
            }
            return(obj);
        }
Beispiel #5
0
        public object[] ConvertForSending(object Item, bool Complete)
        {
            ExtractMembers();
            if (Item == null)
            {
                return(new object[] { null });
            }

            List <object> ObjectArray   = new List <object>();
            List <object> newLastValues = new List <object>();

            for (int i = 0; i < Members.Count; i++)
            {
                object           value     = Members[i].GetValue(Item);
                IMDDataConverter Converter = DataConverters[i];
                if (Complete || LastValues.Count == 0 || Converter.ShouldObjectBeReplicated(LastValues[i], value))
                {
                    object[] dataArray = Converter.ConvertForSending(value, Complete);
                    if (dataArray != null)
                    {
                        ObjectArray.Add($"{i}{SEPARATOR}{dataArray.Length}");
                        ObjectArray.AddRange(dataArray);
                    }
                    else
                    {
                        ObjectArray.Add($"{i}{SEPARATOR}{1}");
                        ObjectArray.Add(null);
                    }
                }
                newLastValues.Add(value);
            }

            MDLog.Trace(LOG_CAT, $"MDCustomClass converting for sending ({MDStatics.GetParametersAsString(ObjectArray.ToArray())})");

            LastValues = newLastValues;
            return(ObjectArray.ToArray());
        }
Beispiel #6
0
        public object[] ConvertForSending(object Item, bool Complete)
        {
            if (Item == null)
            {
                return(new object[] { null });
            }

            // Get commands
            T CReplicator            = (T)Item;
            List <object[]> commands = Complete ? CReplicator.MDGetCommandsForNewPlayer() : CReplicator.MDGetCommands();

            List <object> ReturnList = new List <object>();

            foreach (object[] command in commands)
            {
                // Add length
                ReturnList.Add(command.Length);
                ReturnList.AddRange(command);
            }

            MDLog.Trace(LOG_CAT, $"MDCommandReplicator converting for sending ({MDStatics.GetParametersAsString(ReturnList.ToArray())})");

            return(ReturnList.ToArray());
        }
        private void ClockedCall(uint Tick, ClockedRemoteCall.TypeOfCall Type, string NodePath, string Method,
                                 MDRemoteMode Mode, params object[] Parameters)
        {
            Node Target = GetNodeOrNull(NodePath);

            if (Target == null)
            {
                MDLog.Warn(LOG_CAT, $"Could not find target [{NodePath}] for ClockedRpcCall.");
                return;
            }
            MDLog.Trace(LOG_CAT, $"Got clocked call {Method} on {NodePath} with parameters ({MDStatics.GetParametersAsString(Parameters)})");
            ClockedRemoteCall RemoteCall = new ClockedRemoteCall(Tick, Type, WeakRef(Target), Method, Mode, Multiplayer.GetRpcSenderId(), Parameters);

            // Check if we should already invoke this (if the time has already passed)
            if (!RemoteCall.Invoke(GameClock.GetRemoteTick()))
            {
                ClockedRemoteCallList.Add(RemoteCall);
            }
        }
 private void SendClockedCall(int PeerId, ClockedRemoteCall.TypeOfCall Type, MDReliability Reliability,
                              string NodePath, string Method, MDRemoteMode Mode, params object[] Parameters)
 {
     MDLog.Trace(LOG_CAT, $"Sending clocked call {Method} on {NodePath} with parameters ({MDStatics.GetParametersAsString(Parameters)})");
     if (Reliability == MDReliability.Reliable)
     {
         if (PeerId != -1)
         {
             RpcId(PeerId, nameof(ClockedCall), GameClock.GetTick(), Type, NodePath, Method, Mode, Parameters);
         }
         else
         {
             Rpc(nameof(ClockedCall), GameClock.GetTick(), Type, NodePath, Method, Mode, Parameters);
         }
     }
     else
     {
         if (PeerId != -1)
         {
             RpcUnreliableId(PeerId, nameof(ClockedCall), GameClock.GetTick(), Type, NodePath, Method, Mode,
                             Parameters);
         }
         else
         {
             RpcUnreliable(nameof(ClockedCall), GameClock.GetTick(), Type, NodePath, Method, Mode, Parameters);
         }
     }
 }
        /// <summary>
        /// Sends a clocked RPC call to another client
        /// </summary>
        /// <param name="PeerId">The peer to send to</param>
        /// <param name="Reliability">Reliability to send at</param>
        /// <param name="Target">The node that is the target of our rpc call</param>
        /// <param name="Method">The method we want to invoke on the node</param>
        /// <param name="Parameters">Parameters for the call</param>
        public void SendClockedRpc(int PeerId, MDReliability Reliability, Node Target, string Method,
                                   params object[] Parameters)
        {
            if (PeerId == MDStatics.GetPeerId())
            {
                // This is to ourselves so just invoke
                RpcSenderId = PeerId;
                Target.Invoke(Method, Parameters);
                RpcSenderId = -1;
                return;
            }
            MDRemoteMode Mode         = MDStatics.GetMethodRpcType(Target, Method, Parameters);
            int          MethodNumber = MDStatics.GetMethodNumber(Target, Method, Parameters);

            if (MethodNumber == -1)
            {
                // Abort
                MDLog.Fatal(LOG_CAT, $"Could not find method number for {Target.GetType().ToString()}#{Method}({MDStatics.GetParametersAsString(Parameters)})");
                return;
            }
            MethodInfo MethodInfo = MDStatics.GetMethodInfo(Target, MethodNumber);

            object[] SendingParams = MDStatics.ConvertParametersForSending(MethodInfo, Parameters);
            switch (Mode)
            {
            case MDRemoteMode.Master:
                if (!Target.IsNetworkMaster())
                {
                    // Remote invoke master only
                    SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(),
                                    Mode, SendingParams);
                }

                break;

            case MDRemoteMode.MasterSync:
                if (!Target.IsNetworkMaster())
                {
                    // Remote invoke master only
                    SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(),
                                    Mode, SendingParams);
                }

                Target.Invoke(Method, Parameters);
                break;

            case MDRemoteMode.Puppet:
            case MDRemoteMode.Remote:
                // Remote invoke
                SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(),
                                Mode, SendingParams);
                break;

            case MDRemoteMode.PuppetSync:
            case MDRemoteMode.RemoteSync:
                // Remote invoke and local invoke
                SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(),
                                Mode, SendingParams);
                Target.Invoke(Method, Parameters);
                break;
            }
        }