public static void DispatchBlockingEventPrefix(CallSite site, IMyNetObject targetReplicable) { if (!calls.ContainsKey(site.MethodInfo.Name)) { calls.Add(site.MethodInfo.Name, 0); } calls[site.MethodInfo.Name]++; targets[site.MethodInfo.Name] = targetReplicable?.GetType().Name ?? "x"; if (last2 > DateTimeOffset.Now.ToUnixTimeSeconds() - 5) { return; } last2 = DateTimeOffset.Now.ToUnixTimeSeconds(); foreach (var k in calls.Keys) { Plugin.Log.Info($"called method {k} {calls[k]} times"); } Plugin.Log.Info($"---------------"); foreach (var k in targets.Keys) { Plugin.Log.Info($"{k} {targets[k]}"); } Plugin.Log.Info($"----------------------------------------"); calls.Clear(); targets.Clear(); }
private void AddNetworkObject(NetworkId networkID, IMyNetObject obj) { IMyNetObject foundObj; if (!m_networkIDToObject.TryGetValue(networkID, out foundObj)) { m_networkIDToObject.Add(networkID, obj); m_objectToNetworkID.Add(obj, networkID); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null!"); if (proxyTarget.Target != null) { m_proxyToTarget.Add(proxyTarget.Target, proxyTarget); } } } else { if (obj != null && foundObj != null) { MyLog.Default.WriteLine("Replicated object already exists adding : " + obj.ToString() + " existing : " + foundObj.ToString() + " id : " + networkID.ToString()); } Debug.Fail("Replicated object already exists!"); } }
/// <summary> /// Processes state sync sent by server. /// </summary> public void ProcessStateSync(MyPacket packet) { // Simulated packet loss // if (MyRandom.Instance.NextFloat() > 0.05f) return; m_receiveStream.ResetRead(packet); m_lastStateSyncPacketId = m_receiveStream.ReadByte(); while (m_receiveStream.BytePosition < m_receiveStream.ByteLength) { NetworkId networkID = m_receiveStream.ReadNetworkId(); IMyNetObject obj = GetObjectByNetworkId(networkID); var pos = m_receiveStream.BytePosition; NetProfiler.Begin(obj.GetType().Name); Debug.Assert(obj != null && obj is IMyStateGroup, "IMyStateGroup not found by NetworkId"); ((IMyStateGroup)obj).Serialize(m_receiveStream, null, m_lastStateSyncPacketId, 0); NetProfiler.End(m_receiveStream.ByteLength - pos); } if (!m_acks.Contains(m_lastStateSyncPacketId)) { m_acks.Add(m_lastStateSyncPacketId); } }
private void AddNetworkObject(NetworkId networkID, IMyNetObject obj) { IMyNetObject foundObj; networkObjectLock.AcquireExclusiveUsing(); if (!m_networkIDToObject.TryGetValue(networkID, out foundObj)) { m_networkIDToObject.Add(networkID, obj); m_objectToNetworkID.Add(obj, networkID); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null!"); Debug.Assert(!m_proxyToTarget.ContainsKey(proxyTarget.Target), "Proxy is already added to list!"); if (proxyTarget.Target != null && !m_proxyToTarget.ContainsKey(proxyTarget.Target)) { m_proxyToTarget.Add(proxyTarget.Target, proxyTarget); } } } else { if (obj != null && foundObj != null) { MyLog.Default.WriteLine("Replicated object already exists adding : " + obj.ToString() + " existing : " + foundObj.ToString() + " id : " + networkID.ToString()); } Debug.Fail("Replicated object already exists!"); } networkObjectLock.ReleaseExclusive(); }
//internal void ResetPriorities(EndpointId endpointId) //{ // Debug.Assert(m_clientStates.ContainsKey(endpointId)); // foreach (var entry in m_clientStates[endpointId].StateGroups.Values) // { // entry.ResetPriority(); // } //} // Event dispatch: // 1) Reliable events are sent immediatelly when client has replicable or state group // 2) Unreliable events are added into queue with priority (they added only for relevant replicated objects or state groups) bool ShouldSendEvent(IMyNetObject eventInstance, bool isReliable, ClientData client, out float priority) { if (eventInstance == null) { // Static event priority = 1; return(true); } MyStateDataEntry entry; MyReplicableClientData replicableInfo; if ((eventInstance is IMyStateGroup && client.StateGroups.TryGetValue((IMyStateGroup)eventInstance, out entry))) { // For state group, priority cannot be inherited, because it's changing with time // Maybe add another method IMyStateGroup.GetEventPriority() replicableInfo = client.Replicables[entry.Owner]; priority = 1; return(isReliable || replicableInfo.HasActiveStateSync); } else if (eventInstance is IMyReplicable && (client.Replicables.TryGetValue((IMyReplicable)eventInstance, out replicableInfo) || m_fixedObjects.Contains(eventInstance))) { // Event inherits replicated object priority priority = ((IMyReplicable)eventInstance).GetPriority(client.State); return(isReliable || (priority > 0 && replicableInfo.HasActiveStateSync)); } else { priority = 0; return(false); } }
public void RemoveFixedObject(uint id, IMyNetObject obj) { var netId = new NetworkId(id); m_fixedObjects.Remove(obj); RemoveNetworkedObject(netId, obj); }
protected NetworkId AddNetworkObjectServer(IMyNetObject obj) { Debug.Assert(m_isNetworkAuthority); var id = new NetworkId(m_networkIdGenerator.NextId()); AddNetworkObject(id, obj); return(id); }
/// <summary> /// Add network object with fixed ID. /// </summary> public void AddFixedNetworkObject(uint id, IMyNetObject obj) { Debug.Assert(id != 0, "Zero is invalid id, it cannot be used."); Debug.Assert(id <= m_networkIdGenerator.ReservedCount, "Fixed id not reserved, call ReserveFixedIds"); var netId = new NetworkId(id); AddNetworkObject(netId, obj); m_fixedObjects.Add(obj); }
public bool TryGetNetworkIdByObject(IMyNetObject obj, out NetworkId networkId) { System.Diagnostics.Debug.Assert(obj != null, "NULL in replicables"); if (obj == null) { networkId = NetworkId.Invalid; return(false); } return(m_objectToNetworkID.TryGetValue(obj, out networkId)); }
public NetworkId GetNetworkIdByObject(IMyNetObject obj) { System.Diagnostics.Debug.Assert(obj != null, "NULL in replicables"); if (obj == null) { return(NetworkId.Invalid); } Debug.Assert(m_objectToNetworkID.ContainsKey(obj), "Networked object is not in list"); return(m_objectToNetworkID.GetValueOrDefault(obj, NetworkId.Invalid)); }
protected NetworkId RemoveNetworkedObject(IMyNetObject obj) { NetworkId networkID; if (m_objectToNetworkID.TryGetValue(obj, out networkID)) { RemoveNetworkedObject(networkID, obj); } else { Debug.Fail("RemoveNetworkedObject, object not found!"); } return(networkID); }
string GetGroupName(IMyNetObject obj) { if (obj is IMyReplicable) { return("Replicable objects"); } else if (obj is IMyStateGroup) { return("State groups"); } else { return("Unknown net objects"); } }
protected void RemoveNetworkedObject(NetworkId networkID, IMyNetObject obj) { bool removedId = m_objectToNetworkID.Remove(obj); bool removedObj = m_networkIDToObject.Remove(networkID); Debug.Assert(removedId && removedObj, "Networked object was not removed because it was not in collection"); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null during object remove!"); if (proxyTarget.Target != null) { bool removedProxy = m_proxyToTarget.Remove(proxyTarget.Target); Debug.Assert(removedProxy, "Network object proxy was not removed because it was not in collection"); } } m_networkIdGenerator.Return(networkID.Value); }
private void AddNetworkObject(NetworkId networkID, IMyNetObject obj) { IMyNetObject foundObj; if (!m_networkIDToObject.TryGetValue(networkID, out foundObj)) { m_networkIDToObject.Add(networkID, obj); m_objectToNetworkID.Add(obj, networkID); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null!"); if (proxyTarget.Target != null) { m_proxyToTarget.Add(proxyTarget.Target, proxyTarget); } } } else { Debug.Fail("Replicated object already exists!"); } }
internal override bool DispatchBlockingEvent(BitStream stream, CallSite site, EndpointId recipient, IMyNetObject eventInstance, IMyNetObject blockedNetObj, float unreliablePriority) { Debug.Fail("Client should not call blocking events"); // For client this code is old. Only server can dispatch blocking events. return DispatchEvent(stream, site, recipient, eventInstance, unreliablePriority); }
internal override bool DispatchEvent(BitStream stream, CallSite site, EndpointId target, IMyNetObject instance, float unreliablePriority) { Debug.Assert(site.HasServerFlag, String.Format("Event '{0}' does not have server flag, it can't be invoked on server!", site)); if (site.HasServerFlag) { m_callback.SendEvent(stream, site.IsReliable); //Client.SendMessageToServer(stream, site.Reliability, PacketPriorityEnum.LOW_PRIORITY, MyChannelEnum.Replication); } else if (site.HasClientFlag) { // Invoke locally only when it has ClientFlag and no ServerFlag return(true); } return(false); }
public NetworkId GetNetworkIdByObject(IMyNetObject obj) { Debug.Assert(m_objectToNetworkID.ContainsKey(obj), "Networked object is not in list"); return(m_objectToNetworkID.GetValueOrDefault(obj, NetworkId.Invalid)); }
protected void RemoveNetworkedObject(NetworkId networkID, IMyNetObject obj) { bool removedId = m_objectToNetworkID.Remove(obj); bool removedObj = m_networkIDToObject.Remove(networkID); Debug.Assert(removedId && removedObj, "Networked object was not removed because it was not in collection"); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { bool removedProxy = false; if (proxyTarget.Target != null) { removedProxy = m_proxyToTarget.Remove(proxyTarget.Target); } Debug.Assert(removedProxy, "Network object proxy was not removed because it was not in collection"); } m_networkIdGenerator.Return(networkID.Value); }
protected void AddNetworkObjectClient(NetworkId networkId, IMyNetObject obj) { Debug.Assert(!m_isNetworkAuthority); AddNetworkObject(networkId, obj); }
internal override void ProcessEvent(BitStream stream, CallSite site, object obj, IMyNetObject sendAs, EndpointId source) { // Return when validation fails if (!Invoke(site, stream, obj, source, GetClientData(source), true)) { return; } // Send event in case it has [Broadcast], [BroadcastExcept] or [Client] attribute if (site.HasClientFlag || site.HasBroadcastFlag || site.HasBroadcastExceptFlag) { DispatchEvent(stream, site, source, sendAs, 1.0f); } }
internal override bool DispatchEvent(BitStream stream, CallSite site, EndpointId target, IMyNetObject instance, float unreliablePriority) { Debug.Assert(site.HasServerFlag, String.Format("Event '{0}' does not have server flag, it can't be invoked on server!", site)); if (site.HasServerFlag) { m_callback.SendEvent(stream, site.IsReliable); //Client.SendMessageToServer(stream, site.Reliability, PacketPriorityEnum.LOW_PRIORITY, MyChannelEnum.Replication); } else if (site.HasClientFlag) { // Invoke locally only when it has ClientFlag and no ServerFlag return true; } return false; }
static void Prefix(object __instance, MyPacketDataBitStreamBase data, CallSite site, object obj, IMyNetObject sendAs, Vector3D?position, EndpointId source, ref ProfilerToken?__localProfilerHandle) { if (!MethodIndices.TryGetValue(site.Id, out var methodIndex)) { var methodName = $"{Type.FullName}#OnEvent_{site.MethodInfo.Name}"; methodIndex = StringIndexer.Instance.IndexOf(methodName); MethodIndices.Add(site.Id, methodIndex); } __localProfilerHandle = ProfilerPatch.StartToken(__instance, methodIndex, Category); }
/// <summary> /// Called when event is raised locally to send it to other peer(s). /// Return true to invoke event locally. /// </summary> /// <remarks> /// Invoking event locally is important to be done AFTER event is sent to other peers, /// because invocation can raise another event and order must be preserved. /// Local event invocation is done in optimized way without unnecessary deserialization. /// </remarks> internal abstract bool DispatchEvent(BitStream stream, CallSite site, EndpointId recipient, IMyNetObject eventInstance, float unreliablePriority);
string GetGroupName(IMyNetObject obj) { if (obj is IMyReplicable) return "Replicable objects"; else if (obj is IMyStateGroup) return "State groups"; else return "Unknown net objects"; }
public NetworkId GetNetworkIdByObject(IMyNetObject obj) { Debug.Assert(m_objectToNetworkID.ContainsKey(obj), "Networked object is not in list"); return m_objectToNetworkID.GetValueOrDefault(obj, NetworkId.Invalid); }
public bool TryGetNetworkIdByObject(IMyNetObject obj, out NetworkId networkId) { return m_objectToNetworkID.TryGetValue(obj, out networkId); }
internal override void ProcessEvent(BitStream stream, CallSite site, object obj, IMyNetObject sendAs, EndpointId source) { // Client blindly invokes everything received from server (without validation) Invoke(site, stream, obj, source, null, false); }
protected void RemoveNetworkedObject(NetworkId networkID, IMyNetObject obj) { networkObjectLock.AcquireExclusiveUsing(); bool removedId = m_objectToNetworkID.Remove(obj); bool removedObj = m_networkIDToObject.Remove(networkID); Debug.Assert(removedId && removedObj, "Networked object was not removed because it was not in collection"); var proxyTarget = obj as IMyProxyTarget; if (proxyTarget != null) { Debug.Assert(proxyTarget.Target != null, "IMyProxyTarget.Target is null during object remove!"); if (proxyTarget.Target != null) { bool removedProxy = m_proxyToTarget.Remove(proxyTarget.Target); Debug.Assert(removedProxy, "Network object proxy was not removed because it was not in collection"); } } m_networkIdGenerator.Return(networkID.Value); networkObjectLock.ReleaseExclusive(); }
internal override bool DispatchEvent(BitStream stream, CallSite site, EndpointId target, IMyNetObject eventInstance, float unreliablePriority) { Debug.Assert(site.HasClientFlag || site.HasBroadcastFlag || site.HasBroadcastExceptFlag, String.Format("Event '{0}' does not have Client, Broadcast or BroadcastExcept flag, it can't be invoked on client!", site)); var replicable = eventInstance as IMyReplicable; if (site.HasRefreshReplicableFlag && replicable != null) { RefreshReplicable(replicable); } if (site.HasBroadcastFlag || site.HasBroadcastExceptFlag) { foreach (var client in m_clientStates) { if (site.HasBroadcastExceptFlag && client.Key == target) { continue; } // Send it also to client who invoked this method on server float priority; if (ShouldSendEvent(eventInstance, site.IsReliable, client.Value, out priority)) { DispatchEvent(client.Value, priority * unreliablePriority, client.Key, stream, site.IsReliable); } } } else if (site.HasClientFlag) { Debug.Assert(target.IsValid, "Target cannot be null when invoking Client event"); Debug.Assert(m_clientStates.ContainsKey(target), "Target client not found"); ClientData clientData; float priority; if (m_clientStates.TryGetValue(target, out clientData) && ShouldSendEvent(eventInstance, site.IsReliable, clientData, out priority)) { DispatchEvent(clientData, priority, target, stream, site.IsReliable); } } return(site.HasServerFlag); // Invoke locally when Local flag is set }
internal override bool DispatchEvent(BitStream stream, CallSite site, EndpointId target, IMyNetObject eventInstance, float unreliablePriority) { Debug.Assert(site.HasClientFlag || site.HasBroadcastFlag || site.HasBroadcastExceptFlag, String.Format("Event '{0}' does not have Client, Broadcast or BroadcastExcept flag, it can't be invoked on client!", site)); var replicable = eventInstance as IMyReplicable; if (site.HasRefreshReplicableFlag && replicable != null) { RefreshReplicable(replicable); } if (site.HasBroadcastFlag || site.HasBroadcastExceptFlag) { foreach (var client in m_clientStates) { if (site.HasBroadcastExceptFlag && client.Key == target) continue; // Send it also to client who invoked this method on server float priority; if (ShouldSendEvent(eventInstance, site.IsReliable, client.Value, out priority)) { DispatchEvent(client.Value, priority * unreliablePriority, client.Key, stream, site.IsReliable); } } } else if (site.HasClientFlag) { Debug.Assert(target.IsValid, "Target cannot be null when invoking Client event"); Debug.Assert(m_clientStates.ContainsKey(target), "Target client not found"); ClientData clientData; float priority; if (m_clientStates.TryGetValue(target, out clientData) && ShouldSendEvent(eventInstance, site.IsReliable, clientData, out priority)) { DispatchEvent(clientData, priority, target, stream, site.IsReliable); } } return site.HasServerFlag; // Invoke locally when Local flag is set }
protected sealed override void DispatchEvent <T1, T2, T3, T4, T5, T6, T7, T8>(CallSite callSite, EndpointId recipient, float unreliablePriority, ref T1 arg1, ref T2 arg2, ref T3 arg3, ref T4 arg4, ref T5 arg5, ref T6 arg6, ref T7 arg7, ref T8 arg8) { IMyNetObject sendAs; NetworkId networkId; uint sendId = callSite.Id; if (callSite.MethodInfo.IsStatic) { Debug.Assert(arg1 == null, "First argument (the instance on which is event invoked) should be null for static events"); sendAs = null; networkId = NetworkId.Invalid; } else if (arg1 == null) { throw new InvalidOperationException("First argument (the instance on which is event invoked) cannot be null for non-static events"); } else if (arg1 is IMyEventProxy) { sendAs = GetProxyTarget((IMyEventProxy)arg1); if (sendAs == null) { string msg = "Raising event on object which is not recognized by replication: " + arg1; Debug.Fail(msg); MyLog.Default.WriteLine(msg); return; } sendId += (uint)m_typeTable.Get(sendAs.GetType()).EventTable.Count; // Add max id of Proxy networkId = GetNetworkIdByObject(sendAs); Debug.Assert(object.ReferenceEquals(GetProxyTarget(((IMyProxyTarget)sendAs).Target), sendAs), "There must be one-to-one relationship between IMyEventProxy and IMyEventTarget. Proxy.EventTarget.Target == Proxy"); } else if (arg1 is IMyNetObject) { sendAs = (IMyNetObject)arg1; networkId = GetNetworkIdByObject(sendAs); } else { throw new InvalidOperationException("Instance events may be called only on IMyNetObject or IMyEventProxy"); } NetworkId blockingNetworkId = NetworkId.Invalid; IMyNetObject blockedNetObj = null; if (arg8 is IMyEventProxy && callSite.IsBlocking) { blockedNetObj = GetProxyTarget((IMyEventProxy)arg8); blockingNetworkId = GetNetworkIdByObject(blockedNetObj); } else if (arg8 is IMyEventProxy && !callSite.IsBlocking) { throw new InvalidOperationException("Rising blocking event but event itself does not have Blocking attribute"); } else if (!(arg8 is IMyEventProxy) && callSite.IsBlocking) { throw new InvalidOperationException("Event contain Blocking attribute but blocked event proxy is not set or raised event is not blocking one"); } Debug.Assert(sendId <= 255, "Max 256 events are supported per hierarchy"); m_sendStreamEvent.ResetWrite(); m_sendStreamEvent.WriteNetworkId(networkId); m_sendStreamEvent.WriteNetworkId(blockingNetworkId); m_sendStreamEvent.WriteByte((byte)sendId); // TODO: Compress eventId to necessary number of bits var site = (CallSite <T1, T2, T3, T4, T5, T6, T7>)callSite; using (MySerializerNetObject.Using(this)) { site.Serializer(arg1, m_sendStreamEvent, ref arg2, ref arg3, ref arg4, ref arg5, ref arg6, ref arg7); } bool dispatchRes = false; // If blocking event, than process a little differently. (Internally it will call DispatchEvent anyway) if (!blockingNetworkId.IsInvalid) { dispatchRes = DispatchBlockingEvent(m_sendStreamEvent, callSite, recipient, sendAs, blockedNetObj, unreliablePriority); } else { dispatchRes = DispatchEvent(m_sendStreamEvent, callSite, recipient, sendAs, unreliablePriority); } if (dispatchRes) { InvokeLocally(site, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } }
internal override void ProcessEvent(BitStream stream, CallSite site, object obj, IMyNetObject sendAs, EndpointId source) { // Return when validation fails if (!Invoke(site, stream, obj, source, GetClientData(source), true)) return; // Send event in case it has [Broadcast], [BroadcastExcept] or [Client] attribute if (site.HasClientFlag || site.HasBroadcastFlag || site.HasBroadcastExceptFlag) { DispatchEvent(stream, site, source, sendAs, 1.0f); } }
public bool TryGetNetworkIdByObject(IMyNetObject obj, out NetworkId networkId) { return(m_objectToNetworkID.TryGetValue(obj, out networkId)); }
internal override bool DispatchBlockingEvent(BitStream stream, CallSite site, EndpointId recipient, IMyNetObject eventInstance, IMyNetObject blockedNetObj, float unreliablePriority) { Debug.Fail("Client should not call blocking events"); // For client this code is old. Only server can dispatch blocking events. return(DispatchEvent(stream, site, recipient, eventInstance, unreliablePriority)); }
//internal void ResetPriorities(EndpointId endpointId) //{ // Debug.Assert(m_clientStates.ContainsKey(endpointId)); // foreach (var entry in m_clientStates[endpointId].StateGroups.Values) // { // entry.ResetPriority(); // } //} // Event dispatch: // 1) Reliable events are sent immediatelly when client has replicable or state group // 2) Unreliable events are added into queue with priority (they added only for relevant replicated objects or state groups) bool ShouldSendEvent(IMyNetObject eventInstance, bool isReliable, ClientData client, out float priority) { if (eventInstance == null) { // Static event priority = 1; return true; } MyStateDataEntry entry; MyReplicableClientData replicableInfo; if ((eventInstance is IMyStateGroup && client.StateGroups.TryGetValue((IMyStateGroup)eventInstance, out entry))) { // For state group, priority cannot be inherited, because it's changing with time // Maybe add another method IMyStateGroup.GetEventPriority() replicableInfo = client.Replicables[entry.Owner]; priority = 1; return isReliable || replicableInfo.HasActiveStateSync; } else if (eventInstance is IMyReplicable && (client.Replicables.TryGetValue((IMyReplicable)eventInstance, out replicableInfo) || m_fixedObjects.Contains(eventInstance))) { // Event inherits replicated object priority priority = ((IMyReplicable)eventInstance).GetPriority(client.State); return isReliable || (priority > 0 && replicableInfo.HasActiveStateSync); } else { priority = 0; return false; } }
protected NetworkId RemoveNetworkedObject(IMyNetObject obj) { NetworkId networkID; if (m_objectToNetworkID.TryGetValue(obj, out networkID)) { RemoveNetworkedObject(networkID, obj); } else { Debug.Fail("RemoveNetworkedObject, object not found!"); } return networkID; }
protected NetworkId AddNetworkObjectServer(IMyNetObject obj) { Debug.Assert(m_isNetworkAuthority); var id = new NetworkId(m_networkIdGenerator.NextId()); AddNetworkObject(id, obj); return id; }
/// <summary> /// Called when event is received over network. /// Event can be validated, invoked and/or transferred to other peers. /// </summary> internal abstract void ProcessEvent(BitStream stream, CallSite site, object obj, IMyNetObject sendAs, EndpointId source);
internal override bool DispatchBlockingEvent(BitStream stream, CallSite site, EndpointId target, IMyNetObject targetReplicable, IMyNetObject blockingReplicable, float unreliablePriority) { var blockedRepl = blockingReplicable as IMyReplicable; var replicable = targetReplicable as IMyReplicable; if (site.HasBroadcastFlag || site.HasBroadcastExceptFlag) { foreach (var client in m_clientStates) { if (site.HasBroadcastExceptFlag && client.Key == target) continue; float priority; if (ShouldSendEvent(targetReplicable, site.IsReliable, client.Value, out priority)) { // Register networkId as blocked and streaming has to finish for it. this.TryAddBlockerForClient(client.Value, replicable, blockedRepl); } } } else if (site.HasClientFlag && m_localClientEndpoint != target) { ClientData clientData; // Register networkId as blocked and streaming has to finish for it. if (m_clientStates.TryGetValue(target, out clientData)) { this.TryAddBlockerForClient(clientData, replicable, blockedRepl); } } return DispatchEvent(stream, site, target, targetReplicable, unreliablePriority); }