Пример #1
0
        public McpeWrapper GetBatch()
        {
            lock (_cacheSync)
            {
                if (!isDirty && _cachedBatch != null)
                {
                    return(_cachedBatch);
                }

                ClearCache();

                McpeFullChunkData fullChunkData = McpeFullChunkData.CreateObject();
                fullChunkData.chunkX    = x;
                fullChunkData.chunkZ    = z;
                fullChunkData.chunkData = GetBytes();
                byte[] bytes = fullChunkData.Encode();
                fullChunkData.PutPool();

                var batch = BatchUtils.CreateBatchPacket(bytes, 0, bytes.Length, CompressionLevel.Optimal, true);
                batch.MarkPermanent();
                batch.Encode();

                _cachedBatch = batch;
                _cache       = null;
                isDirty      = false;

                return(_cachedBatch);
            }
        }
Пример #2
0
        internal static McpeWrapper CreateMcpeBatch(byte[] bytes)
        {
            McpeWrapper batch = BatchUtils.CreateBatchPacket(new Memory <byte>(bytes, 0, (int)bytes.Length), CompressionLevel.Optimal, true);

            batch.MarkPermanent();
            batch.Encode();
            return(batch);
        }
Пример #3
0
        private void SendBuffered(int messageCount, MemoryStream memStream)
        {
            if (messageCount == 0)
            {
                return;
            }

            var batch = BatchUtils.CreateBatchPacket(memStream.GetBuffer(), 0, (int)memStream.Length, CompressionLevel.Fastest, false);

            batch.Encode();
            memStream.Position = 0;
            memStream.SetLength(0);

            Server.SendPackage(this, batch);
        }
Пример #4
0
        protected virtual void BroadCastMovement(Player[] players, Entity[] entities)
        {
            DateTime now = DateTime.UtcNow;

            if (players.Length == 0)
            {
                return;
            }

            if (players.Length <= 1 && entities.Length == 0)
            {
                return;
            }

            if (now - _lastBroadcast < TimeSpan.FromMilliseconds(50))
            {
                return;
            }

            DateTime tickTime = _lastSendTime;

            _lastSendTime = DateTime.UtcNow;

            using (MemoryStream stream = MiNetServer.MemoryStreamManager.GetStream())
            {
                int playerMoveCount = 0;
                int entiyMoveCount  = 0;

                foreach (var player in players)
                {
                    if (now - player.LastUpdatedTime <= now - tickTime)
                    {
                        PlayerLocation knownPosition = player.KnownPosition;

                        McpeMovePlayer move = McpeMovePlayer.CreateObject();
                        move.entityId = player.EntityId;
                        move.x        = knownPosition.X;
                        move.y        = knownPosition.Y + 1.62f;
                        move.z        = knownPosition.Z;
                        move.yaw      = knownPosition.Yaw;
                        move.pitch    = knownPosition.Pitch;
                        move.headYaw  = knownPosition.HeadYaw;
                        move.mode     = 0;
                        byte[] bytes = move.Encode();
                        BatchUtils.WriteLength(stream, bytes.Length);
                        stream.Write(bytes, 0, bytes.Length);
                        move.PutPool();
                        playerMoveCount++;
                    }
                }

                foreach (var entity in entities)
                {
                    if (now - entity.LastUpdatedTime <= now - tickTime)
                    {
                        {
                            McpeMoveEntity moveEntity = McpeMoveEntity.CreateObject();
                            moveEntity.entityId    = entity.EntityId;
                            moveEntity.position    = (PlayerLocation)entity.KnownPosition.Clone();
                            moveEntity.position.Y += entity.PositionOffset;
                            byte[] bytes = moveEntity.Encode();
                            BatchUtils.WriteLength(stream, bytes.Length);
                            stream.Write(bytes, 0, bytes.Length);
                            moveEntity.PutPool();
                        }
                        {
                            McpeSetEntityMotion entityMotion = McpeSetEntityMotion.CreateObject();
                            entityMotion.entityId = entity.EntityId;
                            entityMotion.velocity = entity.Velocity;
                            byte[] bytes = entityMotion.Encode();
                            BatchUtils.WriteLength(stream, bytes.Length);
                            stream.Write(bytes, 0, bytes.Length);
                            entityMotion.PutPool();
                        }
                        entiyMoveCount++;
                    }
                }

                if (playerMoveCount == 0 && entiyMoveCount == 0)
                {
                    return;
                }

                if (players.Length == 1 && entiyMoveCount == 0)
                {
                    return;
                }

                McpeBatch batch = BatchUtils.CreateBatchPacket(stream.GetBuffer(), 0, (int)stream.Length, CompressionLevel.Optimal, false);
                batch.AddReferences(players.Length - 1);
                batch.Encode();
                //batch.ValidUntil = now + TimeSpan.FromMilliseconds(50);
                foreach (var player in players)
                {
                    MiNetServer.FastThreadPool.QueueUserWorkItem(() => player.SendPackage(batch));
                }
                _lastBroadcast = DateTime.UtcNow;
            }
        }
Пример #5
0
 internal static McpeBatch CreateMcpeBatch(byte[] bytes)
 {
     return(BatchUtils.CreateBatchPacket(bytes, 0, (int)bytes.Length, CompressionLevel.Optimal, true));
 }
Пример #6
0
        public void DisplaySelection(bool force = false, int particleId = 10)
        {
            if (!force && !ShowSelection)
            {
                return;                                       // don't render at all
            }
            if (force && ShowSelection)
            {
                return;                                     // Will be rendered on regular tick instead
            }
            Level level = Player.Level;

            if (!Monitor.TryEnter(_sync))
            {
                return;
            }

            try
            {
                BoundingBox box = GetSelection();

                var numberOfParticles = box.Height * box.Width * 2 + box.Height * box.Depth * 2;

                bool isBig = numberOfParticles > 500;

                List <McpeLevelEvent> packets = new List <McpeLevelEvent>();

                {
                    //if ((Math.Abs(box.Width) > 0) || (Math.Abs(box.Height) > 0) || (Math.Abs(box.Depth) > 0))
                    {
                        var minX = Math.Min(box.Min.X, box.Max.X);
                        var maxX = Math.Max(box.Min.X, box.Max.X) + 1;

                        var minY = Math.Max(0, Math.Min(box.Min.Y, box.Max.Y));
                        var maxY = Math.Min(255, Math.Max(box.Min.Y, box.Max.Y)) + 1;

                        var minZ = Math.Min(box.Min.Z, box.Max.Z);
                        var maxZ = Math.Max(box.Min.Z, box.Max.Z) + 1;

                        // x/y
                        for (float x = minX; x <= maxX; x++)
                        {
                            for (float y = minY; y <= maxY; y++)
                            {
                                foreach (var z in new float[] { minZ, maxZ })
                                {
                                    if (isBig)
                                    {
                                        if (x != minX && x != maxX && y != minY && y != maxY)
                                        {
                                            continue;
                                        }
                                    }

                                    if (!level.IsAir(new BlockCoordinates((int)x, (int)y, (int)z)))
                                    {
                                        continue;
                                    }

                                    //var particle = new Particle(particleId, Player.Level) {Position = new Vector3(x, y, z) + new Vector3(0.5f, 0.5f, 0.5f)};
                                    //var particle = new Particle(particleId, Player.Level) { Position = new Vector3(x, y, z) };
                                    //particle.Spawn(new[] { Player });

                                    McpeLevelEvent particleEvent = McpeLevelEvent.CreateObject();
                                    particleEvent.eventId  = (short)(0x4000 | 10);
                                    particleEvent.position = new Vector3(x, y, z);
                                    particleEvent.data     = 0;
                                    packets.Add(particleEvent);
                                }
                            }
                        }

                        // x/z
                        //for (float x = minX; x <= maxX; x++)
                        //{
                        //	foreach (var y in new float[] {minY, maxY})
                        //	{
                        //		for (float z = minZ; z <= maxZ; z++)
                        //		{
                        //			if (!level.IsAir(new BlockCoordinates((int) x, (int) y, (int) z))) continue;

                        //			//var particle = new Particle(10, Player.Level) {Position = new Vector3(x, y, z) + new Vector3(0.5f, 0.5f, 0.5f)};
                        //			var particle = new Particle(10, Player.Level) {Position = new Vector3(x, y, z)};
                        //			particle.Spawn(new[] {Player});
                        //		}
                        //	}
                        //}

                        // z/y
                        foreach (var x in new float[] { minX, maxX })
                        {
                            for (float y = minY; y <= maxY; y++)
                            {
                                for (float z = minZ; z <= maxZ; z++)
                                {
                                    if (isBig)
                                    {
                                        if (z != minZ && z != maxZ && y != minY && y != maxY)
                                        {
                                            continue;
                                        }
                                    }

                                    if (!level.IsAir(new BlockCoordinates((int)x, (int)y, (int)z)))
                                    {
                                        continue;
                                    }

                                    //var particle = new Particle(10, Player.Level) {Position = new Vector3(x, y, z) + new Vector3(0.5f, 0.5f, 0.5f)};
                                    //var particle = new Particle(10, Player.Level) { Position = new Vector3(x, y, z) };
                                    //particle.Spawn(new[] { Player });

                                    McpeLevelEvent particleEvent = McpeLevelEvent.CreateObject();
                                    particleEvent.eventId  = (short)(0x4000 | 10);
                                    particleEvent.position = new Vector3(x, y, z);
                                    particleEvent.data     = 0;
                                    packets.Add(particleEvent);
                                }
                            }
                        }
                    }

                    if (packets.Count > 500)
                    {
                        if (force)
                        {
                            Log.Warn($"Selection size is {numberOfParticles}. Number of particles is {packets.Count} ");
                        }

                        return;                         // too many particles
                    }


                    if (packets.Count > 0)
                    {
                        var packet = BatchUtils.CreateBatchPacket(CompressionLevel.Optimal, packets.ToArray());
                        Player.SendPacket(packet);
                        //level.RelayBroadcast(new[] { Player }, packet);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error("Display selection", e);
            }
            finally
            {
                Monitor.Exit(_sync);
            }
        }