/// <summary> /// Marks replicable as successfully created, ready to receive events and state groups data. /// </summary> void SetReplicableReady(NetworkId networkId, IMyReplicable replicable) { MyPendingReplicable pendingReplicable; if (m_pendingReplicables.TryGetValue(networkId, out pendingReplicable)) { var ids = pendingReplicable.StateGroupIds; AddNetworkObjectClient(networkId, replicable); using (m_tmpGroups) { replicable.GetStateGroups(m_tmpGroups); Debug.Assert(ids.Count == m_tmpGroups.Count, "Number of state groups on client and server for replicable does not match"); for (int i = 0; i < m_tmpGroups.Count; i++) { if (m_tmpGroups[i] != replicable) AddNetworkObjectClient(ids[i], m_tmpGroups[i]); } } m_pendingReplicables.Remove(networkId); m_eventBuffer.ProcessEvents(networkId, m_eventHandler); m_sendStream.ResetWrite(); m_sendStream.WriteNetworkId(networkId); m_callback.SendReplicableReady(m_sendStream); } else { // Replicable was already destroyed on server, during it's load on client m_eventBuffer.RemoveEvents(networkId); replicable.OnDestroy(); } }
override protected void AddRoot(IMyReplicable replicable) { System.Diagnostics.Debug.Assert(!replicable.HasToBeChild, "Cannot add children replicables to root!"); m_roots.Add(replicable); m_updateList.List.Add(replicable); }
public MyStateDataEntry(IMyReplicable owner, NetworkId groupId, IMyStateGroup group) { Priority = 0; Owner = owner; GroupId = groupId; Group = group; }
public void ProcessReplicationCreate(MyPacket packet) { m_receiveStream.ResetRead(packet); TypeId typeId = m_receiveStream.ReadTypeId(); NetworkId networkID = m_receiveStream.ReadNetworkId(); byte groupCount = m_receiveStream.ReadByte(); var pendingReplicable = new MyPendingReplicable(); for (int i = 0; i < groupCount; i++) { var id = m_receiveStream.ReadNetworkId(); pendingReplicable.StateGroupIds.Add(id); } Type type = GetTypeByTypeId(typeId); IMyReplicable replicable = (IMyReplicable)Activator.CreateInstance(type); pendingReplicable.DebugObject = replicable; pendingReplicable.IsStreaming = false; m_pendingReplicables.Add(networkID, pendingReplicable); replicable.OnLoad(m_receiveStream, (loaded) => SetReplicableReady(networkID, replicable, loaded)); }
public override HashSet <IMyReplicable> GetDependencies() { m_dependencies.Clear(); MyPlayerCollection playerCollection = MySession.Static.Players; var connectedPlayers = playerCollection.GetOnlinePlayers(); foreach (var player in connectedPlayers) { if (player.Character == Instance) { var broadcasters = Instance.RadioReceiver.GetRelayedBroadcastersForPlayer(player.Identity.IdentityId); foreach (var broadcaster in broadcasters) { IMyReplicable dep = MyExternalReplicable.FindByObject(broadcaster.Entity); if (dep != null) { m_dependencies.Add(dep.GetParent() ?? dep); } } } } return(m_dependencies); }
/// <summary> /// Finds state group of specified type. /// Returns null when group of specified type not found. /// </summary> public static T FindStateGroup <T>(this IMyReplicable obj) where T : class, IMyStateGroup { try { if (obj == null) { return(null); } obj.GetStateGroups(m_tmpStateGroups); foreach (var item in m_tmpStateGroups) { var group = item as T; if (group != null) { return(group); } } return(null); } finally { m_tmpStateGroups.Clear(); } }
void SendReplicationDestroy(IMyReplicable obj, EndpointId clientEndpoint) { m_sendStream.ResetWrite(); m_sendStream.WriteNetworkId(GetNetworkIdByObject(obj)); m_callback.SendReplicationDestroy(m_sendStream, clientEndpoint); //Server.SendMessage(m_sendStream, clientId, PacketReliabilityEnum.RELIABLE, PacketPriorityEnum.LOW_PRIORITY, MyChannelEnum.Replication); }
public void GetChildren(IMyReplicable replicable, List <IMyReplicable> resultChildren) { foreach (var child in GetChildren(replicable)) { resultChildren.Add(child); } }
private void RefreshReplicable(IMyReplicable replicable) { MyTimeSpan now = m_timeFunc(); foreach (var client in m_clientStates) { MyReplicableClientData replicableInfo; bool hasObj = client.Value.Replicables.TryGetValue(replicable, out replicableInfo); bool isRelevant = replicable.GetPriority(client.Value.State) > 0; if (isRelevant) { var dependency = replicable.GetDependency(); isRelevant = dependency == null || client.Value.IsReplicableReady(dependency); } if (!hasObj && isRelevant) { AddForClient(replicable, client.Key, client.Value); } else if (hasObj) { // Hysteresis replicableInfo.UpdateSleep(isRelevant, now); if (replicableInfo.ShouldRemove(now, MaxSleepTime)) { RemoveForClient(replicable, client.Key, client.Value, true); } } } }
public void GetChildren(IMyReplicable replicable, List<IMyReplicable> resultChildren) { foreach (var child in GetChildren(replicable)) { resultChildren.Add(child); } }
public void Destroy(IMyReplicable obj) { Debug.Assert(obj != null); if (!IsTypeReplicated(obj.GetType())) { return; } var id = GetNetworkIdByObject(obj); if (id.IsInvalid) { Debug.Fail("Destroying object which is not present"); return; } // Remove from client states, remove from client replicables, send destroy foreach (var client in m_clientStates) { // TODO: Postpone removing for client (we don't want to peak network when a lot of objects get removed) if (client.Value.Replicables.ContainsKey(obj)) { RemoveForClient(obj, client.Key, client.Value, true); } } RemoveStateGroups(obj); var netId = RemoveNetworkedObject(obj); m_replicables.Remove(netId); }
private void RefreshReplicable(IMyReplicable rep) { foreach (var client in ClientStates) { client.Value.RefreshReplicable(rep, false); } }
public MyCharacterPhysicsStateGroup(MyEntity entity, IMyReplicable ownerReplicable) : base(entity, ownerReplicable) { // This is 9 bits per component which is more than enough (512 discrete values per-axis) m_lowPrecisionOrientation = true; FindSupportDelegate = () => MySupportHelper.FindSupportForCharacter(Entity); }
private void WritePhysics(BitStream stream, MyEntity controlledEntity) { IMyReplicable player = MyExternalReplicable.FindByObject(controlledEntity); if (player == null) { stream.WriteBool(false); return; } var stateGroup = player.FindStateGroup <MyEntityPhysicsStateGroup>(); if (stateGroup == null) { stream.WriteBool(false); return; } bool isResponsible = stateGroup.ResponsibleForUpdate(new EndpointId(Sync.MyId)); stream.WriteBool(isResponsible); if (isResponsible) { stateGroup.Serialize(stream, null, 0, 65535); } }
public MyEntityPhysicsStateGroupWithSupport(MyEntity entity, IMyReplicable ownerReplicable) : base(entity, ownerReplicable) { m_onSupportMove = OnSupportMove; m_onSupportVelocityChanged = OnSupportVelocityChanged; if (Sync.IsServer) OnMoved += PhysicsStateGroup_OnMoved; }
public void GetAllChildren(IMyReplicable replicable, List <IMyReplicable> resultList) { foreach (var child in GetChildren(replicable)) { resultList.Add(child); GetAllChildren(child, resultList); } }
private void UpdateParent() { if (m_parentDirty) { m_parent = GetParent(); m_parentDirty = false; } }
void GetAllChildren(IMyReplicable replicable, List<IMyReplicable> resultList) { foreach (var child in GetChildren(replicable)) { resultList.Add(child); GetAllChildren(child, resultList); } }
public static void RefreshChild(IMyReplicable replicable) { var server = GetReplicationServer(); if (server != null) { server.RefreshChildren(replicable); } }
public MyStateDataEntry(IMyReplicable owner, NetworkId groupId, IMyStateGroup group, IMyReplicable parent) { Priority = 0; Owner = owner; GroupId = groupId; Group = group; GroupType = group.GroupType; Parent = parent; }
private void RemoveForClient(IMyReplicable replicable, EndpointId clientEndpoint, ClientData clientData, bool sendDestroyToClient) { if (sendDestroyToClient) { SendReplicationDestroy(replicable, clientEndpoint); } RemoveClientReplicable(replicable, clientData); Console.WriteLine(String.Format("Sending replication destroy: {0}", GetNetworkIdByObject(replicable))); }
private void RemoveClientReplicable(IMyReplicable replicable, ClientData clientData) { foreach (var g in m_replicableGroups[replicable]) { g.DestroyClientData(clientData.State); clientData.StateGroups.Remove(g); } clientData.Replicables.Remove(replicable); }
public static void ReplicateImmediatelly(IMyReplicable replicable, IMyReplicable dependency = null) { MyReplicationServer replicationServer = GetReplicationServer(); if (replicationServer != null) { replicationServer.ForceReplicable(replicable, dependency); } }
public void ProcessReplicationDestroy(MyPacket packet) { m_receiveStream.ResetRead(packet); NetworkId networkID = m_receiveStream.ReadNetworkId(); MyPendingReplicable pendingReplicable; if (!m_pendingReplicables.TryGetValue(networkID, out pendingReplicable)) // When it wasn't in pending replicables, it's already active and in scene, destroy it { IMyReplicable replicable = (IMyReplicable)GetObjectByNetworkId(networkID); // Debug.Assert(replicable != null, "Client received ReplicationDestroy, but object no longer exists (removed locally?)"); if (replicable != null) { using (m_tmpGroups) { var streamable = replicable as IMyStreamableReplicable; if (streamable != null && streamable.NeedsToBeStreamed) { m_tmpGroups.Add(streamable.GetStreamingStateGroup()); } replicable.GetStateGroups(m_tmpGroups); foreach (var g in m_tmpGroups) { if (g == null) { continue; } if (g != replicable) { RemoveNetworkedObject(g); } g.Destroy(); } } RemoveNetworkedObject(replicable); replicable.OnDestroy(); } } else { m_pendingReplicables.Remove(networkID); if (pendingReplicable.IsStreaming) { IMyStateGroup group = (IMyStateGroup)GetObjectByNetworkId(pendingReplicable.StreamingGroupId); if (group != null) { RemoveNetworkedObject(group); group.Destroy(); } } m_eventBuffer.RemoveEvents(networkID); } }
public ItemsStateGroup(MyInventory entity, IMyReplicable owner, int batch) { Inventory = entity; Batch = batch; _serverData = new Dictionary <Endpoint, InventoryClientData>(); Inventory.ContentsChanged += InventoryChanged; Owner = owner; _server = (MyReplicationServer)MyMultiplayer.Static.ReplicationLayer; }
/// <summary> /// Hack to allow thing like: CreateCharacter, Respawn sent from server /// </summary> public void ForceReplicable(IMyReplicable obj, EndpointId clientEndpoint) { PrepareForceReplicable(obj); var client = m_clientStates[clientEndpoint]; if (!client.Replicables.ContainsKey(obj)) { AddForClient(obj, clientEndpoint, client); } }
/// <summary> /// Destroys replicable for all clients (used for testing and debugging). /// </summary> public void ResetForClients(IMyReplicable obj) { foreach (var client in m_clientStates) { if (client.Value.Replicables.ContainsKey(obj)) { RemoveForClient(obj, client.Key, client.Value, true); } } }
/// <summary> /// This is hack for immediate replication, it's necessary because of logic dependency. /// E.g. Character is created on server, sent to client and respawn message sent immediatelly. /// Should be called only on server. /// </summary> /// <param name="replicable">Replicable to replicate.</param> /// <param name="clientEndpoint">Client who will receive the replicable immediatelly.</param> public static void ReplicateImmediatelly(IMyReplicable replicable, EndpointId clientEndpoint) { var server = GetReplicationServer(); if (server != null && clientEndpoint.Value != Sync.MyId) { Debug.Assert(replicable != null, "Replicable cannot be null"); server.ForceReplicable(replicable, clientEndpoint); } }
public MyEntityPhysicsStateGroupWithSupport(MyEntity entity, IMyReplicable ownerReplicable) : base(entity, ownerReplicable) { m_onSupportMove = OnSupportMove; m_onSupportVelocityChanged = OnSupportVelocityChanged; if (Sync.IsServer) { OnMoved += PhysicsStateGroup_OnMoved; } }
/// <summary> /// This is hack for immediate replication, it's necessary because of logic dependency. /// E.g. Character is created on server, sent to client and respawn message sent immediatelly. /// Should be called only on server. /// </summary> /// <param name="replicable">Replicable to replicate to clients</param> /// <param name="dependency">Replicable will be replicated only to clients who has dependency.</param> public static void ReplicateImmediatelly(IMyReplicable replicable, IMyReplicable dependency = null) { var server = GetReplicationServer(); if (server != null) { Debug.Assert(replicable != null, "Replicable cannot be null"); server.ForceReplicable(replicable, dependency); } }
public static void ForceBothOrNone(IMyReplicable obj, IMyReplicable obj2) { var server = GetReplicationServer(); if (server != null) { Debug.Assert(obj != null, "Proxy cannot be null"); Debug.Assert(obj2 != null, "Proxy2 cannot be null"); server.ForceBothOrNone(obj, obj2); } }
/// <summary> /// Removes all children of replicable. /// Children of children should be already removed! /// </summary> public void RemoveChildren(IMyReplicable replicable) { var children = m_parentToChildren.GetValueOrDefault(replicable, m_empty); while (children.Count > 0) { var e = children.GetEnumerator(); e.MoveNext(); Remove(e.Current); } }
/// <summary> /// Refreshes all children. /// </summary> public void RefreshChildrenHierarchy(IMyReplicable replicable) { using (m_tmpList) { GetAllChildren(replicable, m_tmpList); foreach (var child in m_tmpList) { Refresh(child); } } }
/// <summary> /// Removes replicable, children should be already removed /// </summary> public void Remove(IMyReplicable replicable) { IMyReplicable parent; if (m_childToParent.TryGetValue(replicable, out parent)) // Replicable is child { RemoveChild(replicable, parent); } Debug.Assert(!m_parentToChildren.ContainsKey(replicable), "Removing parent before children are removed"); m_roots.Remove(replicable); }
public MyFloatingObjectPhysicsStateGroup(MyFloatingObject entity, IMyReplicable owner) : base(entity, owner) { m_lowPrecisionOrientation = true; m_prioritySettings.AcceleratingPriority /= 2; m_prioritySettings.LinearMovingPriority /= 2; m_prioritySettings.StoppedPriority /= 2; m_prioritySettings.AcceleratingUpdateCount *= 2; m_prioritySettings.LinearMovingUpdateCount *= 2; m_prioritySettings.StoppedUpdateCount *= 2; }
/// <summary> /// Sets or resets replicable (updates child status and parent). /// Returns true if replicable is root, otherwise false. /// </summary> public void Add(IMyReplicable replicable, out IMyReplicable parent) { if (replicable.IsChild && TryGetDependency(replicable, out parent)) // Add as child { AddChild(replicable, parent); } else // Add as root { parent = null; m_roots.Add(replicable); m_updateQueue.Add(replicable); } }
private void RefreshReplicable(IMyReplicable replicable) { MyTimeSpan now = m_timeFunc(); foreach (var client in m_clientStates) { MyReplicableClientData replicableInfo; bool hasObj = client.Value.Replicables.TryGetValue(replicable, out replicableInfo); bool isRelevant = replicable.GetPriority(client.Value.State) > 0; if(isRelevant) { var dependency = replicable.GetDependency(); isRelevant = dependency == null || client.Value.IsReplicableReady(dependency); } if (!hasObj && isRelevant) { AddForClient(replicable, client.Key, client.Value); } else if (hasObj) { // Hysteresis replicableInfo.UpdateSleep(isRelevant, now); if (replicableInfo.ShouldRemove(now, MaxSleepTime)) RemoveForClient(replicable, client.Key, client.Value, true); } } }
public MyGridPhysicsStateGroup(MyEntity entity, IMyReplicable ownerReplicable) : base(entity, ownerReplicable) { m_positionValidation = ValidatePosition; }
public void RemoveStateGroups(IMyReplicable replicable) { // Remove from actively replicating state groups and replicable foreach (var client in m_clientStates.Values) { RemoveClientReplicable(replicable, client); } // Remove groups foreach (var group in m_replicableGroups[replicable]) { if (group != replicable) RemoveNetworkedObject(group); } m_replicableGroups.Remove(replicable); }
/// <summary> /// Hack to allow thing like: CreateCharacter, Respawn sent from server /// </summary> public void ForceReplicable(IMyReplicable obj, IMyReplicable dependency = null) { PrepareForceReplicable(obj); foreach (var client in m_clientStates) { if (dependency != null) { if (!client.Value.Replicables.ContainsKey(dependency)) { continue; } } if (!client.Value.Replicables.ContainsKey(obj)) { AddForClient(obj, client.Key, client.Value); } } }
private void AddClientReplicable(IMyReplicable replicable, ClientData clientData) { // Add replicable clientData.Replicables.Add(replicable, new MyReplicableClientData()); // Add state groups foreach (var group in m_replicableGroups[replicable]) { var netId = GetNetworkIdByObject(group); clientData.StateGroups.Add(group, new MyStateDataEntry(replicable, netId, group)); group.CreateClientData(clientData.State); } }
public void AddStateGroups(IMyReplicable replicable) { using (m_tmpGroups) { replicable.GetStateGroups(m_tmpGroups); foreach (var group in m_tmpGroups) { if (group != replicable) AddNetworkObjectServer(group); } m_replicableGroups.Add(replicable, new List<IMyStateGroup>(m_tmpGroups)); } }
public void Replicate(IMyReplicable obj) { if (!IsTypeReplicated(obj.GetType())) { Debug.Fail(String.Format("Type '{0}' not replicated, this should be checked before calling Replicate", obj.GetType().Name)); return; } NetworkId networkId = AddNetworkObjectServer(obj); m_replicables.Add(networkId, obj); AddStateGroups(obj); // HACK: test serialization //m_sendStream.ResetWrite(MessageIDEnum.REPLICATION_CREATE); //stateData.Replicate(m_sendStream); }
/// <summary> /// Marks replicable as successfully created, ready to receive events and state groups data. /// </summary> void SetReplicableReady(NetworkId networkId, IMyReplicable replicable, bool loaded) { MyPendingReplicable pendingReplicable; if (m_pendingReplicables.TryGetValue(networkId, out pendingReplicable)) { m_pendingReplicables.Remove(networkId); if (loaded) { var ids = pendingReplicable.StateGroupIds; AddNetworkObjectClient(networkId, replicable); using (m_tmpGroups) { IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null && pendingReplicable.IsStreaming) { var group = streamable.GetStreamingStateGroup(); m_tmpGroups.Add(group); } replicable.GetStateGroups(m_tmpGroups); Debug.Assert(ids.Count == m_tmpGroups.Count, "Number of state groups on client and server for replicable does not match"); for (int i = 0; i < m_tmpGroups.Count; i++) { if (m_tmpGroups[i] != replicable && m_tmpGroups[i].GroupType != StateGroupEnum.Streamining) { AddNetworkObjectClient(ids[i], m_tmpGroups[i]); } } } m_eventBuffer.ProcessEvents(networkId, m_eventHandler, m_isBlockedHandler, NetworkId.Invalid); } else { MyLog.Default.WriteLine("Failed to create replicable ! Type : " + replicable.ToString()); m_eventBuffer.RemoveEvents(networkId); IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null && pendingReplicable.IsStreaming) { var group = streamable.GetStreamingStateGroup(); group.Destroy(); NetworkId streaingGroupId; if (TryGetNetworkIdByObject(group, out streaingGroupId)) { RemoveNetworkedObject(group); } MyLog.Default.WriteLine("removing streaming group for not loaded replicable !"); } } m_sendStream.ResetWrite(); m_sendStream.WriteNetworkId(networkId); m_sendStream.WriteBool(loaded); m_callback.SendReplicableReady(m_sendStream); } else { m_pendingReplicables.Remove(networkId); using (m_tmpGroups) { IMyStreamableReplicable streamable = replicable as IMyStreamableReplicable; if (streamable != null && streamable.NeedsToBeStreamed) { var group = streamable.GetStreamingStateGroup(); m_tmpGroups.Add(group); MyLog.Default.WriteLine("removing streaming group for not loaded replicable !" ); } replicable.GetStateGroups(m_tmpGroups); foreach (var g in m_tmpGroups) { if (g != null) // when terminal repblicable fails to attach to block its state group is null becouase its created inside hook method. { g.Destroy(); } } } replicable.OnDestroy(); } }
public MyGridPhysicsStateGroup(MyEntity entity, IMyReplicable ownerReplicable) : base(entity, ownerReplicable) { }
public MyEntityPhysicsStateGroup(MyEntity entity, IMyReplicable ownerReplicable) { Entity = entity; OwnerReplicable = ownerReplicable; }
private void AddForClient(IMyReplicable replicable, EndpointId clientEndpoint, ClientData clientData) { AddClientReplicable(replicable, clientData); SendReplicationCreate(replicable, clientEndpoint); Console.WriteLine(String.Format("Sending replication create: {0}, {1}", GetNetworkIdByObject(replicable), replicable)); }
void SendReplicationCreate(IMyReplicable obj, EndpointId clientEndpoint) { var typeId = GetTypeIdByType(obj.GetType()); var networkId = GetNetworkIdByObject(obj); var groups = m_replicableGroups[obj]; Debug.Assert(groups.Count <= 255, "Unexpectedly high number of groups"); m_sendStream.ResetWrite(); m_sendStream.WriteTypeId(typeId); m_sendStream.WriteNetworkId(networkId); m_sendStream.WriteByte((byte)groups.Count); for (int i = 0; i < groups.Count; i++) { m_sendStream.WriteNetworkId(GetNetworkIdByObject(groups[i])); } obj.OnSave(m_sendStream); m_callback.SendReplicationCreate(m_sendStream, clientEndpoint); //Server.SendMessage(m_sendStream, clientId, PacketReliabilityEnum.RELIABLE, PacketPriorityEnum.LOW_PRIORITY, MyChannelEnum.Replication); }
bool PrepareForceReplicable(IMyReplicable obj) { Debug.Assert(obj != null); if (!IsTypeReplicated(obj.GetType())) { Debug.Fail(String.Format("Cannot replicate {0}, type is not replicated", obj)); return false; } NetworkId id; if (!TryGetNetworkIdByObject(obj, out id)) { Replicate(obj); } return true; }
/// <summary> /// Destroys replicable for all clients (used for testing and debugging). /// </summary> public void ResetForClients(IMyReplicable obj) { foreach(var client in m_clientStates) { if(client.Value.Replicables.ContainsKey(obj)) { RemoveForClient(obj, client.Key, client.Value, true); } } }
public MySmallObjectPhysicsStateGroup(MyEntity entity, IMyReplicable owner) : base(entity, owner) { m_positionValidation = ValidatePosition; FindSupportDelegate = () => MySupportHelper.FindSupportForCharacter(Entity); }
public bool IsReplicableReady(IMyReplicable replicable) { MyReplicableClientData info; return Replicables.TryGetValue(replicable, out info) && !info.IsPending; }