public void Close() { _levelTicker.Change(Timeout.Infinite, Timeout.Infinite); WaitHandle waitHandle = new AutoResetEvent(false); _levelTicker.Dispose(waitHandle); WaitHandle.WaitAll(new[] { waitHandle }, TimeSpan.FromMinutes(2)); _levelTicker = null; foreach (var entity in Entities.Values.ToArray()) { entity.DespawnEntity(); } Entities.Clear(); foreach (Player player in Players.Values.ToArray()) { player.Disconnect("Unexpected player lingering on close of level: " + player.Username); } Players.Clear(); BlockEntities.Clear(); BlockWithTicks.Clear(); BlockWithTicks = null; BlockEntities = null; Players = null; Entities = null; _worldProvider = null; Log.Info("Closed level: " + LevelId); }
private void GameTick(object source, ElapsedEventArgs e) { _sw.Start(); DayTick(); WeatherTick(); foreach (var blockEvent in BlockWithTicks.ToArray()) { if (blockEvent.Value <= CurrentWorldTime) { var d = GetBlock(blockEvent.Key); d.OnTick(this); BlockWithTicks.Remove(blockEvent.Key); } } foreach (var player in OnlinePlayers.Values.ToArray()) { player.OnTick(); } foreach (var entity in Entities) { entity.OnTick(); } /*if (_saveTick == 3000) * { * _saveTick = 0; * ConsoleFunctions.WriteInfoLine("Saving chunks"); * var sw = new Stopwatch(); * sw.Start(); * SaveChunks(); * sw.Stop(); * ConsoleFunctions.WriteInfoLine("Saving chunks took: " + sw.ElapsedMilliseconds + "MS"); * * GC.Collect(); //Collect garbage * } */ if (_saveTick == 750) { GC.Collect(); _saveTick = 0; } else { _saveTick++; } _sw.Stop(); _lastCalc = _sw.ElapsedMilliseconds; _sw.Reset(); }
private void GameTick(object source, ElapsedEventArgs e) { _sw.Start(); DayTick(); foreach (var blockEvent in BlockWithTicks.ToArray()) { if (blockEvent.Value <= CurrentWorldTime) { GetBlock(blockEvent.Key).OnTick(this); int value; BlockWithTicks.TryRemove(blockEvent.Key, out value); } } foreach (var player in OnlinePlayers.ToArray()) { player.OnTick(); } foreach (var entity in Entities.ToArray()) { entity.OnTick(); } if (_saveTick == 1500) { _saveTick = 0; ConsoleFunctions.WriteInfoLine("Saving chunks"); var sw = new Stopwatch(); sw.Start(); SaveChunks(); sw.Stop(); ConsoleFunctions.WriteInfoLine("Saving chunks took: " + sw.ElapsedMilliseconds + "MS"); ConsoleFunctions.WriteInfoLine("Clearing chunk cache..."); Generator.ClearCache(); //Clear chunk cache GC.Collect(); //Collect garbage } else { _saveTick++; } if (_saveTick == 750) { GC.Collect(); } _sw.Stop(); _lastCalc = _sw.ElapsedMilliseconds; _sw.Reset(); }
public void Close() { //_levelTicker.Change(Timeout.Infinite, Timeout.Infinite); //WaitHandle waitHandle = new AutoResetEvent(false); //_levelTicker.Dispose(waitHandle); //WaitHandle.WaitAll(new[] {waitHandle}, TimeSpan.FromMinutes(2)); //_levelTicker = null; _tickerHighPrecisionTimer.Dispose(); foreach (var entity in Entities.Values.ToArray()) { entity.DespawnEntity(); } Entities.Clear(); foreach (Player player in Players.Values.ToArray()) { player.Disconnect("Unexpected player lingering on close of level: " + player.Username); } Players.Clear(); BlockEntities.Clear(); BlockWithTicks.Clear(); BlockWithTicks = null; BlockEntities = null; Players = null; Entities = null; AnvilWorldProvider provider = _worldProvider as AnvilWorldProvider; if (provider != null) { foreach (var chunk in provider._chunkCache) { chunk.Value?.ClearCache(); } } _worldProvider = null; Log.Info("Closed level: " + LevelId); }
private void WorldTick(object sender) { if (_tickTimer.ElapsedMilliseconds < 40) { if (Log.IsDebugEnabled) { Log.Warn($"World tick came too fast: {_tickTimer.ElapsedMilliseconds} ms"); } return; } if (Log.IsDebugEnabled && _tickTimer.ElapsedMilliseconds >= 100) { Log.Error($"Time between World tick too too long: {_tickTimer.ElapsedMilliseconds} ms"); } _tickTimer.Restart(); try { TickTime++; if (IsWorldTimeStarted) { CurrentWorldTime += 1.25; } if (CurrentWorldTime > _worldDayCycleTime) { CurrentWorldTime = 0; } if (TickTime % 100 == 0) { //McpeSetTime message = McpeSetTime.CreateObject(); //message.time = (int)CurrentWorldTime; //message.started = (byte)(IsWorldTimeStarted ? 0x80 : 0x00); //RelayBroadcast(players, message); } // Block updates foreach (KeyValuePair <BlockCoordinates, long> blockEvent in BlockWithTicks) { Log.Debug($"Have block tick for {blockEvent.Key}"); if (blockEvent.Value <= TickTime) { GetBlock(blockEvent.Key).OnTick(this); long value; BlockWithTicks.TryRemove(blockEvent.Key, out value); } } // Block entity updates foreach (BlockEntity blockEntity in BlockEntities.ToArray()) { blockEntity.OnTick(this); } // Entity updates Entity[] entities = Entities.Values.ToArray(); foreach (Entity entity in entities) { entity.OnTick(); } Player[] players = GetSpawnedPlayers(); PlayerCount = players.Length; // Player tick foreach (var player in players) { if (player.IsSpawned) { player.OnTick(); } } // Send player movements //if (TickTime % 2 == 0) BroadCastMovement(players, entities); //if (TickTime%100 == 0) // Every 5 seconds //{ // var staledPlayers = GetStaledPlayers(players); // foreach (var p in staledPlayers) // { // ThreadPool.QueueUserWorkItem(delegate(object state) // { // Player player = (Player) state; // player.Disconnect("Staled."); // }, p); // } //} if (Log.IsDebugEnabled && _tickTimer.ElapsedMilliseconds >= 50) { Log.Error($"World tick too too long: {_tickTimer.ElapsedMilliseconds} ms"); } } catch (Exception e) { Log.Error("World ticking", e); } finally { LastTickProcessingTime = _tickTimer.ElapsedMilliseconds; AvarageTickProcessingTime = ((AvarageTickProcessingTime * 9) + _tickTimer.ElapsedMilliseconds) / 10L; } }
private void WorldTick(object sender) { if (!Monitor.TryEnter(_tickSync)) { return; } _tickTimer.Restart(); try { TickTime++; if (IsWorldTimeStarted) { CurrentWorldTime += 1.25; } if (CurrentWorldTime > _worldDayCycleTime) { CurrentWorldTime = 0; } if (TickTime % 100 == 0) { //McpeSetTime message = McpeSetTime.CreateObject(); //message.time = (int)CurrentWorldTime; //message.started = (byte)(IsWorldTimeStarted ? 0x80 : 0x00); //RelayBroadcast(players, message); } // Block updates foreach (KeyValuePair <BlockCoordinates, long> blockEvent in BlockWithTicks) { if (blockEvent.Value <= TickTime) { GetBlock(blockEvent.Key).OnTick(this); long value; BlockWithTicks.TryRemove(blockEvent.Key, out value); } } // Block entity updates foreach (BlockEntity blockEntity in BlockEntities.ToArray()) { blockEntity.OnTick(this); } // Entity updates Entity[] entities = Entities.ToArray(); foreach (Entity entity in entities) { entity.OnTick(); } Player[] players = GetSpawnedPlayers(); PlayerCount = players.Length; // Player tick foreach (var player in players) { if (player.IsSpawned) { player.OnTick(); } } // Send player movements BroadCastMovement(players, entities); if (TickTime % 100 == 0) // Every 5 seconds { var staledPlayers = GetStaledPlayers(players); foreach (var p in staledPlayers) { ThreadPool.QueueUserWorkItem(delegate(object state) { Player player = (Player)state; player.Disconnect("Staled."); }, p); } } } finally { LastTickProcessingTime = _tickTimer.ElapsedMilliseconds; AvarageTickProcessingTime = ((AvarageTickProcessingTime * 9) + _tickTimer.ElapsedMilliseconds) / 10L; Monitor.Exit(_tickSync); } }
private void WorldTick(object sender) { if (!Monitor.TryEnter(_tickSync)) { return; } _tickTimer.Restart(); try { TickTime++; Player[] players = GetSpawnedPlayers(); if (IsWorldTimeStarted) { CurrentWorldTime += 1.25; } if (CurrentWorldTime > _worldDayCycleTime) { CurrentWorldTime = 0; } if (TickTime % 100 == 0) { //McpeSetTime message = McpeSetTime.CreateObject(); //message.time = (int) CurrentWorldTime; //message.started = (byte) (IsWorldTimeStarted ? 0x80 : 0x00); //RelayBroadcast(players, message); } // Block updates foreach (KeyValuePair <BlockCoordinates, long> blockEvent in BlockWithTicks.ToArray()) { if (blockEvent.Value <= TickTime) { GetBlock(blockEvent.Key).OnTick(this); long value; BlockWithTicks.TryRemove(blockEvent.Key, out value); } } // Block entity updates foreach (BlockEntity blockEntity in BlockEntities.ToArray()) { blockEntity.OnTick(this); } // Entity updates foreach (Entity entity in Entities.ToArray()) { entity.OnTick(); } // Player tick foreach (Player player in players) { player.OnTick(); } // Send player movements Player[] updatedPlayers = GetUpdatedPlayers(players); BroadCastMovement(players, updatedPlayers); } finally { LastTickProcessingTime = _tickTimer.ElapsedMilliseconds; Monitor.Exit(_tickSync); } }