public override void HandleOnServer(NodeSegmentCreateCommand command, Player player) { //Extensions.NodeAndSegmentExtension.NetSegmentLocked = true; NetInfo netinfo = PrefabCollection <NetInfo> .GetPrefab(command.InfoIndex); var startNode = Extensions.NodeAndSegmentExtension.NodeIDDictionary[command.StartNode]; //uses the Dictionary of the Client and Servers different NodeID to convert the recived NodeID the the NodeID of the reciever var endNode = Extensions.NodeAndSegmentExtension.NodeIDDictionary[command.EndNode]; StartEndNode startEndNode = new StartEndNode(Singleton <NetManager> .instance.m_nodes.m_buffer[startNode].m_position, Singleton <NetManager> .instance.m_nodes.m_buffer[endNode].m_position); Extensions.NodeAndSegmentExtension.StartEndNodeDictionary.Add(startEndNode, 100); // add dummy segment to hinder occilation Singleton <NetManager> .instance.CreateSegment(out ushort id, ref Singleton <SimulationManager> .instance.m_randomizer, netinfo, startNode, endNode, command.StartDirection, command.EndDirection, Singleton <SimulationManager> .instance.m_currentBuildIndex, command.ModifiedIndex, false); Extensions.NodeAndSegmentExtension.StartEndNodeDictionary[startEndNode] = id; }
public override void HandleOnServer(NodeSegmentCommand command, Player player) { Extensions.NodeAndSegmentExtension._NetSegmentLocked = true; lock (Extensions.NodeAndSegmentExtension._netSegment) { NetInfo netinfo = PrefabCollection <NetInfo> .GetPrefab(command.InfoIndex); var StartNode = Extensions.NodeAndSegmentExtension.NodeIDDictionary[command.StartNode]; //uses the Dictionary of the Client and Servers different NodeID to convert the recived NodeID the the NodeID of the reciever var EndNode = Extensions.NodeAndSegmentExtension.NodeIDDictionary[command.EndNode]; lock (Extensions.NodeAndSegmentExtension.StartEndNodeDictionary) { Singleton <NetManager> .instance.CreateSegment(out ushort id, ref Singleton <SimulationManager> .instance.m_randomizer, netinfo, StartNode, EndNode, command.StartDirection, command.EndDirection, Singleton <SimulationManager> .instance.m_currentBuildIndex, command.ModifiedIndex, false); StartEndNode startEndNode = new StartEndNode(Singleton <NetManager> .instance.m_nodes.m_buffer[StartNode].m_position, Singleton <NetManager> .instance.m_nodes.m_buffer[EndNode].m_position); Extensions.NodeAndSegmentExtension.StartEndNodeDictionary.Add(startEndNode, id); } } Extensions.NodeAndSegmentExtension._NetSegmentLocked = false; }
public static Dictionary <StartEndNode, ushort> StartEndNodeDictionary = new Dictionary <StartEndNode, ushort>(); //This dictionary contains a combination of start and end nodes, is used to ensure against NodesSegment ocilliation between server and client public override void OnAfterSimulationTick() { base.OnAfterSimulationTick(); if (_initialised == false) //This is run when initialized, it ensures that the dictionaries are filled and that we can change for later changes { switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: for (ushort i = 0; i < _netNode.Length; i++) { if (_netNode[i].m_position != _nonVector) { NodeVectorDictionary.Add(_netNode[i].m_position, i); NodeIDDictionary.Add(i, i); } } for (ushort i = 0; i < NetSegments.Length; i++) { if (NetSegments[i].m_startNode != 0) { StartEndNode startEndNode = new StartEndNode(_netNode[NetSegments[i].m_startNode].m_position, _netNode[NetSegments[i].m_endNode].m_position); StartEndNodeDictionary.Add(startEndNode, i); } } for (ushort i = 0; i < _ZoneBlock.Length; i++) { if (_ZoneBlock[i].m_position != _nonVector) { ZoneVectorDictionary.Add(_ZoneBlock[i].m_position, i); } } NetSegments.CopyTo(_lastNetSegment, 0); _netNode.CopyTo(_lastNetNode, 0); _ZoneBlock.CopyTo(_LastZoneBlock, 0); _initialised = true; break; case MultiplayerRole.Client: for (ushort i = 0; i < _netNode.Length; i++) { if (_netNode[i].m_position != _nonVector) { NodeVectorDictionary.Add(_netNode[i].m_position, i); NodeIDDictionary.Add(i, i); } } for (ushort i = 0; i < NetSegments.Length; i++) { if (NetSegments[i].m_startNode != 0) { StartEndNode startEndNode = new StartEndNode(_netNode[NetSegments[i].m_startNode].m_position, _netNode[NetSegments[i].m_endNode].m_position); StartEndNodeDictionary.Add(startEndNode, i); } } for (ushort i = 0; i < _ZoneBlock.Length; i++) { if (_ZoneBlock[i].m_position != _nonVector) { ZoneVectorDictionary.Add(_ZoneBlock[i].m_position, i); } } NetSegments.CopyTo(_lastNetSegment, 0); _netNode.CopyTo(_lastNetNode, 0); _ZoneBlock.CopyTo(_LastZoneBlock, 0); _initialised = true; break; } } if (_treadRunning == false && _initialised == true) { _treadRunning = true; new Thread(() => { for (int i = 0; i < _netNode.Length; i++) //this checks if any new nodes has been created by cheching if any nodes positions has been changed { if (_netNode[i].m_position != _lastNetNode[i].m_position) { _nodeChange = true; break; } } foreach (var Id in NodeVectorDictionary) // this checks if any nodes has been removed, by controlling if any of the nodes that we have created, has been deleted { if (_nodeChange == true) { break; } ushort value = Id.Value; if (_netNode[value].m_flags == 0) { _nodeReleased = true; break; } } for (ushort i = 0; i < Singleton <ZoneManager> .instance.m_blocks.m_buffer.Length; i++) { if (_nodeChange == true | _nodeReleased == true) { break; } if (_ZoneBlock[i].m_position != _nonVector && !ZoneVectorDictionary.ContainsKey(_ZoneBlock[i].m_position)) // The zones are created when road is created, this detect all zoon created and adds it to dictionary { ZoneVectorDictionary.Add(_ZoneBlock[i].m_position, i); } if (_ZoneBlock[i].m_zone1 != _LastZoneBlock[i].m_zone1 | _ZoneBlock[i].m_zone2 != _LastZoneBlock[i].m_zone2) //this checks if anything have changed { ZoneChange = true; break; } } if (_nodeChange == true) { for (uint i = 0; i < _netNode.Length; i++) { if (_netNode[i].m_position != _lastNetNode[i].m_position) { var position = _netNode[i].m_position; var infoIndex = _netNode[i].m_infoIndex; var nodeId = i; _updateNetNode = true; if (!NodeVectorDictionary.ContainsKey(_netNode[i].m_position)) { NodeVectorDictionary.Add(_netNode[i].m_position, (ushort)i); switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: Command.SendToClients(new NodeCreateCommand { Position = position, InfoIndex = infoIndex, NodeId = nodeId }); break; case MultiplayerRole.Client: Command.SendToServer(new NodeCreateCommand { Position = position, InfoIndex = infoIndex, NodeId = nodeId }); break; } } } } for (int i = 0; i < NetSegments.Length; i++) { if (NetSegments[i].m_startNode != _lastNetSegment[i].m_startNode | NetSegments[i].m_endNode != _lastNetSegment[i].m_endNode) { var startnode = NetSegments[i].m_startNode; var endnode = NetSegments[i].m_endNode; var startDirection = NetSegments[i].m_startDirection; var enddirection = NetSegments[i].m_endDirection; var modifiedIndex = NetSegments[i].m_modifiedIndex; var infoIndex = NetSegments[i].m_infoIndex; _updateNetSegment = true; StartEndNode startEndNode = new StartEndNode(_netNode[startnode].m_position, _netNode[endnode].m_position); if (!StartEndNodeDictionary.ContainsKey(startEndNode)) { StartEndNodeDictionary.Add(startEndNode, (ushort)i); switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: Command.SendToClients(new NodeSegmentCreateCommand { StartNode = startnode, EndNode = endnode, StartDirection = startDirection, EndDirection = enddirection, ModifiedIndex = modifiedIndex, InfoIndex = infoIndex }); break; case MultiplayerRole.Client: Command.SendToServer(new NodeSegmentCreateCommand { StartNode = startnode, EndNode = endnode, StartDirection = startDirection, EndDirection = enddirection, ModifiedIndex = modifiedIndex, InfoIndex = infoIndex }); break; } } } } if (_updateNetSegment) { NetSegments.CopyTo(_lastNetSegment, 0); _updateNetSegment = false; } if (_updateNetNode) { _netNode.CopyTo(_lastNetNode, 0); _updateNetNode = false; } UnityEngine.Debug.Log("Done Updating"); _nodeChange = false; } if (_nodeReleased == true) { foreach (var Id in NodeVectorDictionary) { if (_netNode[Id.Value].m_flags == 0) { switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: Command.SendToClients(new NodeReleaseCommand { NodeId = Id.Value }); break; case MultiplayerRole.Client: Command.SendToServer(new NodeReleaseCommand { NodeId = Id.Value }); break; } _vectorList.Add(Id.Key); foreach (var ID in NodeIDDictionary.Where(kvp => kvp.Value == Id.Value).ToList()) { NodeIDDictionary.Remove(Id.Value); } } } ; foreach (var vector in _vectorList) { NodeVectorDictionary.Remove(vector); } _vectorList.Clear(); _nodeReleased = false; } if (ZoneChange == true) { for (ushort i = 0; i < Singleton <ZoneManager> .instance.m_blocks.m_buffer.Length; i++) { if (_ZoneBlock[i].m_zone1 != _LastZoneBlock[i].m_zone1 | _ZoneBlock[i].m_zone2 != _LastZoneBlock[i].m_zone2) //this runs through all Zoneblocks and detect if the zonetype has changed { Command.SendToAll(new ZoneCommand { Position = _ZoneBlock[i].m_position, Zone1 = _ZoneBlock[i].m_zone1, Zone2 = _ZoneBlock[i].m_zone2 }); } } _ZoneBlock.CopyTo(_LastZoneBlock, 0); ZoneChange = false; } _treadRunning = false; }).Start(); } }
public override void OnAfterSimulationTick() { base.OnAfterSimulationTick(); if (Initialised == false) //This is run when initiallised, it ensures that the dictionaries are filled and that we can change for later changes { switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: for (ushort i = 0; i < _netNode.Length; i++) { if (_netNode[i].m_position != NonVector) { VectorDictionary.Add(_netNode[i].m_position, i); NodeIDDictionary.Add(i, i); } } for (ushort i = 0; i < _netSegment.Length; i++) { if (_netSegment[i].m_startNode != 0) { StartEndNode startEndNode = new StartEndNode(_netNode[_netSegment[i].m_startNode].m_position, _netNode[_netSegment[i].m_endNode].m_position); StartEndNodeDictionary.Add(startEndNode, i); } } _netSegment.CopyTo(_lastNetSegment, 0); _netNode.CopyTo(_lastNetNode, 0); Initialised = true; break; case MultiplayerRole.Client: for (ushort i = 0; i < _netNode.Length; i++) { if (_netNode[i].m_position != NonVector) { VectorDictionary.Add(_netNode[i].m_position, i); NodeIDDictionary.Add(i, i); } } for (ushort i = 0; i < _netSegment.Length; i++) { if (_netSegment[i].m_startNode != 0) { StartEndNode startEndNode = new StartEndNode(_netNode[_netSegment[i].m_startNode].m_position, _netNode[_netSegment[i].m_endNode].m_position); StartEndNodeDictionary.Add(startEndNode, i); } } _netSegment.CopyTo(_lastNetSegment, 0); _netNode.CopyTo(_lastNetNode, 0); Initialised = true; break; } } if (TreadRunning == false && Initialised == true) { TreadRunning = true; new Thread(() => { for (int i = 0; i < _netNode.Length; i++) //this checks for changes by cheching if a node has been changed { if (_netNode[i].m_position != _lastNetNode[i].m_position) { NodeChange = true; break; } } if (NodeChange == true) { lock (_netNode) { if (_NetSegmentLocked) { Thread.Sleep(1000); } lock (_netSegment) { for (int i = 0; i < _netNode.Length; i++) { if (_netNode[i].m_position != _lastNetNode[i].m_position) { var position = _netNode[i].m_position; var infoIndex = _netNode[i].m_infoIndex; var nodeId = i; UpdateNetNode = true; if (!VectorDictionary.ContainsKey(_netNode[i].m_position)) { VectorDictionary.Add(_netNode[i].m_position, (ushort)i); switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: Command.SendToClients(new NodeCommand { Position = position, InfoIndex = infoIndex, NodeID = nodeId }); //UnityEngine.Debug.Log("Command send"); break; case MultiplayerRole.Client: Command.SendToServer(new NodeCommand { Position = position, InfoIndex = infoIndex, NodeID = nodeId }); //UnityEngine.Debug.Log("Command send"); break; } Thread.Sleep(50); //The biggest problem with this implementation is that we need to ensure that the Reciver first recieves and add all the Nodes before the Nodes segments are recieved } } } for (int i = 0; i < _netSegment.Length; i++) { if (_netSegment[i].m_startNode != _lastNetSegment[i].m_startNode) { var startnode = _netSegment[i].m_startNode; var endnode = _netSegment[i].m_endNode; var startDirection = _netSegment[i].m_startDirection; var enddirection = _netSegment[i].m_endDirection; var modifiedIndex = _netSegment[i].m_modifiedIndex; var infoIndex = _netSegment[i].m_infoIndex; UpdateNetSegment = true; StartEndNode startEndNode = new StartEndNode(_netNode[startnode].m_position, _netNode[endnode].m_position); if (!StartEndNodeDictionary.ContainsKey(startEndNode)) { StartEndNodeDictionary.Add(startEndNode, (ushort)i); Thread.Sleep(50); //The biggest problem with this implementation is that we need to ensure that the Reciver first recieves and add all the Nodes before the Nodes segments are recieved switch (MultiplayerManager.Instance.CurrentRole) { case MultiplayerRole.Server: Command.SendToClients(new NodeSegmentCommand { StartNode = startnode, EndNode = endnode, StartDirection = startDirection, EndDirection = enddirection, ModifiedIndex = modifiedIndex, InfoIndex = infoIndex }); break; case MultiplayerRole.Client: Command.SendToServer(new NodeSegmentCommand { StartNode = startnode, EndNode = endnode, StartDirection = startDirection, EndDirection = enddirection, ModifiedIndex = modifiedIndex, InfoIndex = infoIndex }); break; } } //UnityEngine.Debug.Log("Command send"); //UnityEngine.Debug.Log($"NetSegment created: {i}"); } } if (UpdateNetSegment) { _netSegment.CopyTo(_lastNetSegment, 0); UnityEngine.Debug.Log("NetSegment Updated"); UpdateNetSegment = false; } if (UpdateNetNode) { _netNode.CopyTo(_lastNetNode, 0); UnityEngine.Debug.Log("NetNode Updated"); UpdateNetNode = false; } } } } TreadRunning = false; }).Start(); } }