using System; using System.Net; using System.Net.Sockets; namespace RoboidControl { /// /// A site server is a participant which provides a shared simulated environment /// public class SiteServer : ParticipantUDP { /// /// Create a new site server /// /// public SiteServer(int port = 7681) : base(port) { this.name = "Site Server"; Participant.AddParticipant(this); Console.Write($"Prepare receive on port {port}"); this.endPoint = new IPEndPoint(IPAddress.Any, port); this.udpClient = new UdpClient(port); this.udpClient.BeginReceive(new AsyncCallback(result => ReceiveUDP(result)), null); } /// /// Close the site /// public void Close() { this.udpClient?.Close(); } #region Update protected override void UpdateMyThings(ulong currentTimeMS) { // We don't use foreach to prevent the 'Collection was modified' error int n = this.things.Count; for (int ix = 0; ix < n; ix++) { Thing thing = this.things[ix]; if (thing == null) continue; thing.Update(currentTimeMS, false); if (this.isIsolated == false) { // Send to all other participants //foreach (Participant participant in Participant.participants) { for (int participantIx = 0; participantIx < Participant.participants.Count; participantIx++) { Participant participant = Participant.participants[participantIx]; if (participant == null || participant == this) continue; PoseMsg poseMsg = new(thing.owner.networkId, thing); this.Send(participant, poseMsg); BinaryMsg binaryMsg = new(thing.owner.networkId, thing); this.Send(participant, binaryMsg); } } } } #endregion Update #region Receive protected override void Process(Participant sender, ParticipantMsg msg) { base.Process(sender, msg); if (msg.networkId != sender.networkId) { //Console.WriteLine($"{this.name} received New Participant -> {sender.networkId}"); this.Send(sender, new NetworkIdMsg(sender.networkId)); } } protected override void Process(Participant sender, NetworkIdMsg msg) { } protected override void Process(Participant sender, ThingMsg msg) { Console.WriteLine($"SiteServer: Process thing [{msg.networkId}/{msg.thingId}] {msg.thingType} {msg.parentId} "); Thing thing = sender.Get(msg.networkId, msg.thingId); if (thing == null) thing = new Thing(sender, msg.networkId, msg.thingId, msg.thingType); if (msg.parentId != 0) { thing.parent = sender.Get(msg.networkId, msg.parentId); if (thing.parent == null) Console.WriteLine($"Could not find parent [{msg.networkId}/{msg.parentId}]"); } else { // Console.Write($"Dropped {thing.id}"); thing.parent = null; } } #endregion Receive } }