99 lines
3.5 KiB
C#

using System;
using System.Net;
using System.Net.Sockets;
namespace RoboidControl {
/// <summary>
/// A site server is a participant which provides a shared simulated environment
/// </summary>
public class SiteServer : ParticipantUDP {
/// <summary>
/// Create a new site server
/// </summary>
/// <param name="port"></param>
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);
}
/// <summary>
/// Close the site
/// </summary>
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
}
}