/// <summary>
///
/// </summary>
/// <param name="map"></param>
void ServerTaskFunc ( string map, string postCommand )
{
var netConfig = new NetPeerConfiguration(Game.GameID);
netConfig.Port = Game.Network.Port;
netConfig.MaximumConnections = 32;
netConfig.UnreliableSizeBehaviour = NetUnreliableSizeBehaviour.NormalFragmentation;
if (Debugger.IsAttached) {
netConfig.ConnectionTimeout = float.MaxValue;
Log.Message("SV: Debugger is attached: ConnectionTimeout = {0} sec", netConfig.ConnectionTimeout);
}
netConfig.EnableMessageType( NetIncomingMessageType.ConnectionApproval );
netConfig.EnableMessageType( NetIncomingMessageType.DiscoveryRequest );
netConfig.EnableMessageType( NetIncomingMessageType.DiscoveryResponse );
netConfig.EnableMessageType( NetIncomingMessageType.ConnectionLatencyUpdated );
var server = new NetServer( netConfig );
notifications = new Queue<string>();
Log.Message("SV: Start: {0} {1}", map, postCommand);
var snapshotQueue = new SnapshotQueue(32);
var serverFrames = 0L;
//var accumulatedElapsedTime = TimeSpan.FromTicks(0);
//var maxElapsedTime = TimeSpan.FromMilliseconds(1000);
//var previousTicks = (long)0;
//
// configure & start server :
//
try {
server.Start();
//
// start game specific stuff :
//
atoms = new AtomCollection();
LoadContent( map );
atoms.Lock();
//
// invoke post-start command :
//
if (postCommand!=null) {
Game.Invoker.Push( postCommand );
}
// Timer and fixed timestep stuff :
// http://gafferongames.com/game-physics/fix-your-timestep/
var accumulator = TimeSpan.Zero;
var stopwatch = new Stopwatch();
stopwatch.Start();
var currentTime = stopwatch.Elapsed;
var time = stopwatch.Elapsed;
//
// server loop :
//
while ( !killToken.IsCancellationRequested ) {
_retryTick:
var targetDelta = TimeSpan.FromTicks( (long)(10000000 / TargetFrameRate) );
var newTime = stopwatch.Elapsed;
var frameTime = newTime - currentTime;
currentTime = newTime;
accumulator += frameTime;
if ( accumulator < targetDelta ) {
Thread.Sleep(1);
goto _retryTick;
}
while ( accumulator > targetDelta ) {
//var svTime = new GameTime( time, targetDelta );
var svTime = new GameTime( serverFrames, time, targetDelta );
serverFrames++;
//
// Do actual server stuff :
//
UpdateNetworkAndLogic( svTime, server, snapshotQueue );
accumulator -= targetDelta;
time += targetDelta;
}
}
foreach ( var conn in server.Connections ) {
conn.Disconnect("Server disconnected");
}
} catch ( Exception e ) {
Log.PrintException( e, "Server error: {0}", e.Message );
foreach ( var conn in server.Connections ) {
conn.Disconnect(string.Format("Server error: {0}", e.Message));
}
} finally {
//
// kill game specific stuff :
// try...catch???
//
UnloadContent();
//
// shutdown connection :
//
server.Shutdown("Server shutdown");
Log.Message("SV: Shutdown");
notifications = null;
killToken = null;
serverTask = null;
server = null;
pings = null;
}
}