public sealed override async void ServerInvoke(SpawnConfig config, IProtoTrigger trigger, IServerZone zone) { var key = new CurrentlyExecutingTaskKey(config, trigger, zone); if (!this.executingEntries.Add(key)) { // cannot schedule new request Logger.Warning( "The spawning task is already active - cannot schedule a new spawn task until it's completed"); return; } await serverSpawnSemaphore.WaitAsync(Api.CancellationToken); try { Logger.Info(new StringBuilder("Spawn script \"", capacity: 256) .Append(this.ShortId) .Append("\" for zone \"") .Append(zone.ProtoGameObject.ShortId) .Append("\": spawn started")); await this.ServerRunSpawnTaskAsync(config, trigger, zone); } finally { this.executingEntries.Remove(key); serverSpawnSemaphore.Release(); } }
public sealed override async void ServerInvoke(SpawnConfig config, IProtoTrigger trigger, IServerZone zone) { var key = new CurrentlyExecutingTaskKey(config, trigger, zone); if (!this.executingEntries.Add(key)) { // cannot schedule new request Logger.Warning( "The spawning task is already active - cannot schedule a new spawn task until it's completed"); return; } // Don't use tasks semaphore during the initial spawn. // This way new players cannot connect to the server until the spawn scripts have ended // (the initial spawn is not async anyway so semaphore doesn't do anything good here). var isInitialSpawn = trigger is null || trigger is TriggerWorldInit; if (!isInitialSpawn) { await ServerSpawnTasksSemaphore.WaitAsync(Api.CancellationToken); } try { Logger.Info(new StringBuilder("Spawn script \"", capacity: 256) .Append(this.ShortId) .Append("\" for zone \"") .Append(zone.ProtoGameObject.ShortId) .Append("\": spawn started")); await this.ServerRunSpawnTaskAsync(config, trigger, zone); } finally { this.executingEntries.Remove(key); if (!isInitialSpawn) { ServerSpawnTasksSemaphore.Release(); } } }