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