Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        public void ClearEntities()
        {
            foreach (var entity in Entities.ToArray())
            {
                Remove(entity.Key);
            }

            foreach (var blockEntity in BlockEntities.ToArray())
            {
                BlockEntities.TryRemove(blockEntity.Key, out _);
            }
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
 public bool RemoveBlockEntity(BlockCoordinates coordinates)
 {
     return(BlockEntities.TryRemove(coordinates, out _));
 }
Exemple #10
0
 public bool TryGetBlockEntity(BlockCoordinates coordinates, out BlockEntity entity)
 {
     return(BlockEntities.TryGetValue(coordinates, out entity));
 }
Exemple #11
0
 public bool AddBlockEntity(BlockCoordinates coordinates, BlockEntity entity)
 {
     entity.KnownPosition = coordinates;
     entity.Block         = World.GetBlockState(coordinates).Block;
     return(BlockEntities.TryAdd(coordinates, entity));
 }
Exemple #12
0
        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);
            }
        }
Exemple #13
0
 public void RemoveBlockEntity(BlockCoordinates coordinates)
 {
     BlockEntities.TryRemove(coordinates, out _);
 }
Exemple #14
0
 public bool AddBlockEntity(BlockCoordinates coordinates, BlockEntity entity)
 {
     entity.KnownPosition = coordinates;
     return(BlockEntities.TryAdd(coordinates, entity));
 }
Exemple #15
0
 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));
 }
Exemple #16
0
        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;
            }
        }
Exemple #17
0
        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);
            }
        }