/// <summary> /// Returns the connection that matches the supplied target. /// Returns the server for Server or the first controller for Controllers. /// </summary> internal NetConnection GetTarget(RpcTarget target, NetView view) { switch (target) { case RpcTarget.Server: return(view.Server); case RpcTarget.Controllers: return(view.Controllers[0]); } NetLog.Error("Invalid RpcTarget for GetTarget. Only RpcTarget.Server or RpcTarget.Controllers can be used."); return(null); }
private void StartHandoff(NetView view, NetZone peer) { Debug.Log("Trying To Handoff"); view.SendCreatorData(peer.Server); view.Server = peer.Server; foreach (NetConnection connection in view.Controllers) { if (connection.View == view) { connection.InternalScope = view.Scope; } } ViewManager.DestroyView(view); }
/// <summary> Send overload that creates the NetMessage for the RPC. </summary> internal void Send(int viewId, bool reliable, string methodName, RpcTarget target, params object[] parameters) { if (!Socket.Rpc.HasId(methodName)) { NetLog.Error("Send failed: RPC method name has not been assigned an ID."); return; } if (!ViewLookup.ContainsKey(viewId)) { return; } NetView view = ViewLookup[viewId]; var netMessage = NetMessage.Create(Socket.Rpc.NameToId(methodName), (uint)viewId, parameters, reliable); Send(view, netMessage, target); }
private void IncrementalHandoffCheck() { int pos = incHandoffFrame * handoffBatchSize; for (int i = pos; i < pos + handoffBatchSize; i++) { if (i >= ViewManager.Views.Count) { break; } NetView view = ViewManager.Views[i]; if (view.Server != Socket.Self) { continue; } float dist = Vector3.Distance(view.Scope.Position, self.Position); if (dist < self.HandoverDistance) { continue; } for (int j = 0; j < peers.Count; j++) { NetZone peer = peers[j]; float peerDist = Vector3.Distance(view.Scope.Position, peer.Position); if (peerDist > peer.HandoverMinDistance && (dist < self.HandoverMaxDistance || dist < peerDist)) { continue; } StartHandoff(view, peer); break; } } incHandoffFrame++; if (incHandoffFrame != (Application.targetFrameRate * 2)) { return; } incHandoffFrame = 0; handoffBatchSize = (ViewManager.Views.Count / (Application.targetFrameRate * 2)) + 1; }
/// <summary> Sends command to all connected clients to destroy the provided view. </summary> private void SendDestroyView(NetView view) { var destroyViewMessage = NetMessage.Create((ushort)ViewCmd.DestroyView, 0, 1, true); destroyViewMessage.Parameters[0] = view.Id; for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (connection.IsServer) { continue; } if (view.Group == 0 || connection.InGroup(view.Group)) { connection.Send(destroyViewMessage); } } }
/// <summary> Post-instantiation configuration of NetView. </summary> private void RegisterNetView(NetView view) { if (view.CachedRpcObjects == null) { view.SetRpcCache(RpcInfoCache.CreateInstanceLookup(view.gameObject)); } view.Scope.Trans = view.gameObject.transform; view.Socket = Socket; view.ViewManager = this; if (!ViewLookup.ContainsKey(view.Id)) { ViewLookup.Add(view.Id, view); } if (!Views.Contains(view)) { Views.Add(view); } }
/// <summary> The provided scope is updated if the provided view has gone in or out of scope. /// False is returned if there is no change. </summary> internal bool UpdateScope(NetScope source, NetView view) { bool scopeChanged = false; float distance = Vector3.Distance(source.Position, view.Scope.Position); // If the source scope is configured to override, use its scope distances instead: var rulesScope = source.TakePrecedence ? source : view.Scope; if (view.Scope.CalcDisabled || distance > rulesScope.OutScopeDist) { if (!source.In(view.Id)) { return(false); } scopeChanged = true; source.SetOut(view.Id); } else if (distance < rulesScope.InScopeDist) { if (!source.In(view.Id)) { scopeChanged = true; } if (distance < rulesScope.LevelOne) { source.SetIn(view.Id, 1); } else if (distance < rulesScope.LevelTwo) { source.SetIn(view.Id, 2); } else { source.SetIn(view.Id, 3); } } return(scopeChanged); }
/// <summary> Calculates scope for every connection against the provided view's scope. /// This is useful, for example, when creating a new view so that it can be immediately /// instantiated since a delay may be undesireable. </summary> internal void FullScopeCalculation(NetView view) { if (view.Server != Socket.Self) { return; } for (int i = 0; i < Socket.Connections.Count; i++) { NetConnection connection = Socket.Connections[i]; if (connection.IsServer || !connection.HasScope) { continue; } if (view.IsController(connection)) { view.SendInstantiateData(connection); } else if (connection.InGroup(view.Group) && view.CanInstantiateFor(connection) && UpdateScope(connection.Scope, view)) { view.SendInstantiateData(connection); } } }
public NetView CreateView(int group, string prefabBase, NetStream instantiateData) { NetView view = CreateView(null, group, prefabBase, instantiateData); return(view); }
public NetView CreateView(NetConnection controller, string prefabBase, NetStream instantiateData) { NetView view = CreateView(controller, 0, prefabBase, instantiateData); return(view); }
/// <summary> Sends an RPC to connections that are in-scope for the provided view. </summary> internal void Send(NetView view, NetMessage netMessage, RpcTarget target) { switch (target) { case (RpcTarget.All): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (!connection.HasScope) { continue; } if (view.Group != 0 && !connection.InGroup(view.Group)) { continue; } if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame) || view.IsController(connection)) { connection.Send(netMessage); } } break; case (RpcTarget.Controllers): foreach (NetConnection controller in view.Controllers) { if (controller == Socket.Self) { continue; } controller.Send(netMessage); } break; case (RpcTarget.NonControllers): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (connection.IsServer || !connection.HasScope) { continue; } if (view.IsController(connection)) { continue; } if (view.Group != 0 && !connection.InGroup(view.Group)) { continue; } if ((netMessage.Reliable && connection.Scope.In(view.Id)) || connection.Scope.In(view.Id, syncFrame)) { connection.Send(netMessage); } } break; case (RpcTarget.Server): if (view.Server != Socket.Self) { view.Server.Send(netMessage); } else { NetLog.Warning("Trying to send message to self."); } break; case (RpcTarget.AllInclOutOfScope): for (int i = 0; i < Socket.Connections.Count; i++) { var connection = Socket.Connections[i]; if (view.Group != 0 && !connection.InGroup(view.Group)) { continue; } connection.Send(netMessage); } break; } }