public void SetBlockEntity(BlockEntity blockEntity, bool broadcast = true) { ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(blockEntity.Coordinates.X >> 4, blockEntity.Coordinates.Z >> 4)); chunk.SetBlockEntity(blockEntity.Coordinates, blockEntity.GetCompound()); if (blockEntity.UpdatesOnTick) { BlockEntities.Add(blockEntity); } if (!broadcast) { return; } Nbt nbt = new Nbt { NbtFile = new NbtFile { BigEndian = false, UseVarInt = true, RootTag = blockEntity.GetCompound() } }; var entityData = McpeBlockEntityData.CreateObject(); entityData.namedtag = nbt; entityData.coordinates = blockEntity.Coordinates; RelayBroadcast(entityData); }
public void SetBlockEntity(BlockEntity blockEntity, bool broadcast = true) { ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(blockEntity.Coordinates.X >> 4, blockEntity.Coordinates.Z >> 4)); chunk.SetBlockEntity(blockEntity.Coordinates, blockEntity.GetCompound()); if (blockEntity.UpdatesOnTick) { BlockEntities.Add(blockEntity); } if (!broadcast) { return; } Nbt nbt = new Nbt { NbtFile = new NbtFile { BigEndian = false, RootTag = blockEntity.GetCompound() } }; var entityData = new McpeTileEntityData { namedtag = nbt, x = blockEntity.Coordinates.X, y = (byte)blockEntity.Coordinates.Y, z = blockEntity.Coordinates.Z }; RelayBroadcast(entityData); }
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); }
public void ClearEntities() { foreach (var entity in Entities.ToArray()) { Remove(entity.Key); } foreach (var blockEntity in BlockEntities.ToArray()) { BlockEntities.TryRemove(blockEntity.Key, out _); } }
private void LoadNbtBlockEntity(NbtTag nbtTag) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue; int z = blockEntityTag["z"].IntValue; var coords = new BlockCoordinates(x, y, z); Debug.WriteLine($"Found TileEntity at {x},{y},{z}: {nbtTag["id"].StringValue}"); BlockEntities.Add(coords, blockEntityTag); }
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); }
public void RemoveBlockEntity(BlockCoordinates blockCoordinates) { ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(blockCoordinates.X >> 4, blockCoordinates.Z >> 4)); var nbt = chunk.GetBlockEntity(blockCoordinates); if (nbt == null) { return; } var blockEntity = BlockEntities.FirstOrDefault(entity => entity.Coordinates == blockCoordinates); if (blockEntity != null) { BlockEntities.Remove(blockEntity); } chunk.RemoveBlockEntity(blockCoordinates); }
public BlockEntity GetBlockEntity(BlockCoordinates blockCoordinates) { var blockEntity = BlockEntities.FirstOrDefault(entity => entity.Coordinates == blockCoordinates); if (blockEntity != null) { return(blockEntity); } ChunkColumn chunk = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(blockCoordinates.X >> 4, blockCoordinates.Z >> 4)); NbtCompound nbt = chunk?.GetBlockEntity(blockCoordinates); if (nbt == null) { return(null); } string id = null; var idTag = nbt.Get("id"); if (idTag != null) { id = idTag.StringValue; } if (string.IsNullOrEmpty(id)) { return(null); } blockEntity = BlockEntityFactory.GetBlockEntityById(id); if (blockEntity == null) { return(null); } blockEntity.Coordinates = blockCoordinates; blockEntity.SetCompound(nbt); return(blockEntity); }
public bool RemoveBlockEntity(BlockCoordinates coordinates) { return(BlockEntities.TryRemove(coordinates, out _)); }
public bool TryGetBlockEntity(BlockCoordinates coordinates, out BlockEntity entity) { return(BlockEntities.TryGetValue(coordinates, out entity)); }
public bool AddBlockEntity(BlockCoordinates coordinates, BlockEntity entity) { entity.KnownPosition = coordinates; entity.Block = World.GetBlockState(coordinates).Block; return(BlockEntities.TryAdd(coordinates, entity)); }
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); } }
public void RemoveBlockEntity(BlockCoordinates coordinates) { BlockEntities.TryRemove(coordinates, out _); }
public bool AddBlockEntity(BlockCoordinates coordinates, BlockEntity entity) { entity.KnownPosition = coordinates; return(BlockEntities.TryAdd(coordinates, entity)); }
public bool AddBlockEntity(BlockCoordinates coordinates, BlockEntity entity) { //entity.Block = GetBlockState(coordinates.X & 0x0f, coordinates.Y & 0xf, coordinates.Z & 0x0f).Block; return(BlockEntities.TryAdd(coordinates, entity)); }
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++; 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); } }