Пример #1
0
        public void SendLogin(string username)
        {
            Skin skin = new Skin {
                Slim = false, Texture = Encoding.Default.GetBytes(new string('Z', 8192))
            };

            skin.SkinType = "Standard_Custom";
            //Skin skin = new Skin { Slim = false, Texture = Encoding.Default.GetBytes(new string('Z', 16384)) };
            var packet = new McpeLogin()
            {
                username      = username,
                protocol      = 38,
                protocol2     = 38,
                clientId      = ClientId,
                clientUuid    = new UUID(Guid.NewGuid().ToByteArray()),
                serverAddress = _serverEndpoint.Address + ":" + _serverEndpoint.Port,
                clientSecret  = "iwmvi45hm85oncyo58",
                //clientSecret = Encoding.ASCII.GetString(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("" + ClientId + _serverEndpoint.Address + _serverEndpoint.Port))),
                skin = skin,
            };

            byte[] buffer = Player.CompressBytes(packet.Encode(), CompressionLevel.Fastest, true);

            McpeBatch batch = new McpeBatch();

            batch.payloadSize = buffer.Length;
            batch.payload     = buffer;
            batch.Encode();

            SendPackage(batch);
            LoginSent = true;
        }
Пример #2
0
        public McpeBatch GetBatch()
        {
            lock (_cacheSync)
            {
                if (_cache != null && _cachedBatch != null)
                {
                    return(_cachedBatch);
                }

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

                MemoryStream memStream = new MemoryStream();
                memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                memStream.Write(bytes, 0, bytes.Length);

                McpeBatch batch  = McpeBatch.CreateObject();
                byte[]    buffer = Player.CompressBytes(memStream.ToArray(), CompressionLevel.Optimal);
                batch.payloadSize = buffer.Length;
                batch.payload     = buffer;
                batch.Encode();
                batch.MarkPermanent();

                _cachedBatch = batch;

                return(batch);
            }
        }
Пример #3
0
        public McpeBatch GetBatch()
        {
            if (_cache != null && _cachedBatch != null)
            {
                return(_cachedBatch);
            }

            McpeFullChunkData fullChunkData = McpeFullChunkData.CreateObject();

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

            McpeBatch batch = McpeBatch.CreateObject();

            byte[] buffer = Player.CompressBytes(bytes, CompressionLevel.Optimal);
            batch.payloadSize = buffer.Length;
            batch.payload     = buffer;
            batch.Encode();
            batch.MarkPermanent();

            _cachedBatch = batch;

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

                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(batch);
            }
        }
Пример #5
0
        public McpeBatch GetBatch()
        {
            lock (_cacheSync)
            {
                if (!isDirty && _cachedBatch != null)
                {
                    return(_cachedBatch);
                }

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

                McpeBatch batch;
                using (MemoryStream memStream = MiNetServer.MemoryStreamManager.GetStream())
                {
                    memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                    memStream.Write(bytes, 0, bytes.Length);
                    batch = Player.CreateBatchPacket(memStream.GetBuffer(), 0, (int)memStream.Length, CompressionLevel.Optimal);
                    batch.MarkPermanent();
                    batch.Encode();
                }

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

                return(batch);
            }
        }
Пример #6
0
        internal void HandlePackage(Package message, PlayerNetworkSession playerSession)
        {
            if (message == null)
            {
                return;
            }

            TraceReceive(message);

            if (typeof(UnknownPackage) == message.GetType())
            {
                return;
            }

            if (typeof(McpeBatch) == message.GetType())
            {
                McpeBatch batch = (McpeBatch)message;

                var messages = new List <Package>();

                // Get bytes
                byte[] payload = batch.payload;
                // Decompress bytes

                MemoryStream stream = new MemoryStream(payload);
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                }
                stream.ReadByte();
                using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    // Get actual package out of bytes
                    MemoryStream destination = new MemoryStream();
                    defStream2.CopyTo(destination);
                    byte[] internalBuffer = destination.ToArray();
                    messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                }
                foreach (var msg in messages)
                {
                    msg.DatagramSequenceNumber = batch.DatagramSequenceNumber;
                    msg.OrderingChannel        = batch.OrderingChannel;
                    msg.OrderingIndex          = batch.OrderingIndex;
                    HandlePackage(msg, playerSession);
                    msg.PutPool();
                }

                return;
            }

            message.Source = "HandlePackage";

            Player player = playerSession.Player;

            if (player != null)
            {
                player.HandlePackage(message);
            }
        }
Пример #7
0
        internal static McpeBatch CreateMcpeBatch(byte[] bytes)
        {
            McpeBatch batch = BatchUtils.CreateBatchPacket(bytes, 0, (int)bytes.Length, CompressionLevel.Optimal, true);

            batch.MarkPermanent();
            batch.Encode();
            return(batch);
        }
Пример #8
0
        public object Clone()
        {
            ChunkColumn cc = (ChunkColumn)MemberwiseClone();

            //public int x;
            //public int z;
            //public bool isDirty;

            //public byte[] biomeId = ArrayOf<byte>.Create(256, 2);
            cc.biomeId = (byte[])biomeId.Clone();

            //public int[] biomeColor = ArrayOf<int>.Create(256, 1);
            cc.biomeColor = (int[])biomeColor.Clone();

            //public byte[] height = ArrayOf<byte>.Create(256, 0);
            cc.height = (byte[])height.Clone();

            //public byte[] blocks = new byte[16 * 16 * 128];
            cc.blocks = (byte[])blocks.Clone();

            //public NibbleArray metadata = new NibbleArray(16 * 16 * 128);
            cc.metadata = (NibbleArray)metadata.Clone();

            //public NibbleArray blocklight = new NibbleArray(16 * 16 * 128);
            cc.blocklight = (NibbleArray)blocklight.Clone();

            //public NibbleArray skylight = new NibbleArray(16 * 16 * 128);
            cc.skylight = (NibbleArray)skylight.Clone();

            //public IDictionary<BlockCoordinates, NbtCompound> BlockEntities = new Dictionary<BlockCoordinates, NbtCompound>();
            cc.BlockEntities = new Dictionary <BlockCoordinates, NbtCompound>();
            foreach (KeyValuePair <BlockCoordinates, NbtCompound> blockEntityPair in BlockEntities)
            {
                cc.BlockEntities.Add(blockEntityPair.Key, (NbtCompound)blockEntityPair.Value.Clone());
            }

            //private byte[] _cache;
            if (_cache != null)
            {
                cc._cache = (byte[])_cache.Clone();
            }

            //private McpeBatch _cachedBatch = null;
            McpeBatch batch = McpeBatch.CreateObject();

            batch.payloadSize = _cachedBatch.payloadSize;
            batch.payload     = _cachedBatch.payload;
            batch.Encode();
            batch.MarkPermanent();

            cc._cachedBatch = batch;

            //private object _cacheSync = new object();
            _cacheSync = new object();

            return(cc);
        }
Пример #9
0
 public static McpeBatch CreateBatchPacket(byte[] input, int offset, int length, CompressionLevel compressionLevel, bool writeLen)
 {
     using (var stream = CompressIntoStream(input, offset, length, compressionLevel, writeLen))
     {
         var batch = McpeBatch.CreateObject();
         batch.payload = stream.ToArray();
         batch.Encode();
         return(batch);
     }
 }
Пример #10
0
        internal void ClearCache()
        {
            lock (_cacheSync)
            {
                if (_cachedBatch != null)
                {
                    _cachedBatch.MarkPermanent(false);
                    _cachedBatch.PutPool();

                    _cachedBatch = null;
                }
            }
        }
Пример #11
0
        internal static McpeBatch CreateMcpeBatch(byte[] bytes)
        {
            MemoryStream memStream = MiNetServer.MemoryStreamManager.GetStream();

            memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
            memStream.Write(bytes, 0, bytes.Length);

            McpeBatch batch = McpeBatch.CreateObject();

            byte[] buffer = Player.CompressBytes(memStream.ToArray(), CompressionLevel.Optimal);
            batch.payloadSize = buffer.Length;
            batch.payload     = buffer;
            batch.Encode(true);
            return(batch);
        }
Пример #12
0
        /// <summary>
        ///     Handles the specified package.
        /// </summary>
        /// <param name="message">The package.</param>
        /// <param name="senderEndpoint">The sender's endpoint.</param>
        private void HandlePackage(Package message, PlayerNetworkSession playerSession)
        {
            TraceReceive(message);

            if (typeof(UnknownPackage) == message.GetType())
            {
                return;
            }

            if (typeof(McpeBatch) == message.GetType())
            {
                McpeBatch batch = (McpeBatch)message;

                var messages = new List <Package>();

                // Get bytes
                byte[] payload = batch.payload;
                // Decompress bytes

                MemoryStream stream = new MemoryStream(payload);
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                }
                stream.ReadByte();
                using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    // Get actual package out of bytes
                    MemoryStream destination = new MemoryStream();
                    defStream2.CopyTo(destination);
                    byte[] internalBuffer = destination.ToArray();
                    messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                }
                foreach (var msg in messages)
                {
                    HandlePackage(msg, playerSession);
                }
            }

            playerSession.Player.HandlePackage(message);
            playerSession.LastUpdatedTime = DateTime.UtcNow;

            if (typeof(DisconnectionNotification) == message.GetType())
            {
                PlayerNetworkSession value;
                _playerSessions.TryRemove(playerSession.EndPoint, out value);
            }
        }
Пример #13
0
        private void OnBatch(Package message)
        {
            McpeBatch batch = (McpeBatch)message;

            var messages = new List <Package>();

            // Get bytes
            byte[] payload = batch.payload;
            // Decompress bytes

            MemoryStream stream = new MemoryStream(payload);

            if (stream.ReadByte() != 0x78)
            {
                throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
            }
            stream.ReadByte();
            using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
            {
                // Get actual package out of bytes
                MemoryStream destination = new MemoryStream();
                defStream2.CopyTo(destination);
                destination.Position = 0;
                NbtBinaryReader reader = new NbtBinaryReader(destination, true);
                do
                {
                    int    len            = reader.ReadInt32();
                    byte[] internalBuffer = reader.ReadBytes(len);
                    var    package        = PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer);
                    messages.Add(package);

                    if (!(package is McpeFullChunkData))
                    {
                        Log.Debug($"Batch: {package.GetType().Name} 0x{package.Id:x2} \n{Package.HexDump(internalBuffer)}");
                    }
                } while (destination.Position < destination.Length);
            }
            foreach (var msg in messages)
            {
                msg.DatagramSequenceNumber = batch.DatagramSequenceNumber;
                msg.OrderingChannel        = batch.OrderingChannel;
                msg.OrderingIndex          = batch.OrderingIndex;
                HandlePackage(msg);
                msg.PutPool();
            }
        }
Пример #14
0
        public void DespawnFromAll(Player player)
        {
            lock (_playerWriteLock)
            {
                List <Player> spawnedPlayers = GetSpawnedPlayers().ToList();

                McpePlayerList playerListMessage = McpePlayerList.CreateObject();
                playerListMessage.records = new PlayerRemoveRecords(spawnedPlayers);
                var bytes = playerListMessage.Encode();
                playerListMessage.records = null;

                MemoryStream memStream = new MemoryStream();
                memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                memStream.Write(bytes, 0, bytes.Length);

                McpeBatch batch  = McpeBatch.CreateObject();
                byte[]    buffer = Player.CompressBytes(memStream.ToArray(), CompressionLevel.Optimal);
                batch.payloadSize = buffer.Length;
                batch.payload     = buffer;
                batch.Encode();
                player.SendPackage(batch);

                foreach (Player spawnedPlayer in spawnedPlayers)
                {
                    SendRemoveForPlayer(player, spawnedPlayer, false);
                }

                McpePlayerList playerList = McpePlayerList.CreateObject();
                playerList.records = new PlayerRemoveRecords {
                    player
                };
                playerList.Encode();
                playerList.records = null;
                RelayBroadcast(player, playerList);

                McpeRemovePlayer removePlayerMessage = McpeRemovePlayer.CreateObject();
                removePlayerMessage.clientUuid = player.ClientUuid;
                removePlayerMessage.entityId   = player.EntityId;
                RelayBroadcast(player, removePlayerMessage);
            }
        }
Пример #15
0
        public void SendMoveList(List <McpeMovePlayer> movePlayerPackages)
        {
            if (!IsConnected)
            {
                return;
            }

            //if (Level.TickTime%4 != 0) return;

            int messageCount = 0;

            MemoryStream stream = new MemoryStream();

            foreach (var movePlayer in movePlayerPackages)
            {
                if (movePlayer.entityId != EntityId)
                {
                    messageCount++;
                    byte[] bytes = movePlayer.Encode();
                    stream.Write(bytes, 0, bytes.Length);
                }

                movePlayer.PutPool();
            }

            if (messageCount > 0)
            {
                McpeBatch batch  = McpeBatch.CreateObject();
                byte[]    buffer = CompressBytes(stream.ToArray());
                batch.payloadSize = buffer.Length;
                batch.payload     = buffer;
                batch.Encode();

                Server.SendPackage(this, new List <Package> {
                    batch
                }, _mtuSize, ref _reliableMessageNumber);
                //Server.SendPackage(EndPoint, messages, _mtuSize, ref _reliableMessageNumber);
            }
        }
Пример #16
0
        public void SendLogin(string username)
        {
            Skin skin = new Skin {
                Slim = false, Texture = Encoding.Default.GetBytes(new string('Z', 8192))
            };
            var packet = new McpeLogin()
            {
                clientId = 12345,
                username = username,
                protocol = 27,
                skin     = skin
            };

            McpeBatch batch = new McpeBatch();

            byte[] buffer = CompressBytes(packet.Encode());

            batch.payloadSize = buffer.Length;
            batch.payload     = buffer;

            SendPackage(batch);
        }
Пример #17
0
        private List <Package> HandleBatch(McpeBatch batch)
        {
            var messages = new List <Package>();

            // Get bytes
            byte[] payload = batch.payload;
            // Decompress bytes

            Console.WriteLine("Package:\n" + Package.HexDump(payload));

            MemoryStream stream = new MemoryStream(payload);

            if (stream.ReadByte() != 0x78)
            {
                throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
            }
            stream.ReadByte();
            using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
            {
                // Get actual package out of bytes
                MemoryStream destination = new MemoryStream();
                defStream2.CopyTo(destination);
                destination.Position = 0;
                NbtBinaryReader reader         = new NbtBinaryReader(destination, true);
                int             len            = reader.ReadInt32();
                byte[]          internalBuffer = reader.ReadBytes(len);

                Console.WriteLine($"Package [len={len}:\n" + Package.HexDump(internalBuffer));

                messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer, "mcpe") ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                if (destination.Length > destination.Position)
                {
                    throw new Exception("Have more data");
                }
            }

            return(messages);
        }
Пример #18
0
        public static McpeBatch CreateBatchPacket(byte[] input, int offset, int length, CompressionLevel compressionLevel, bool writeLen)
        {
            var batch = McpeBatch.CreateObject();

            //using (var stream = CompressIntoStream(input, offset, length, compressionLevel, writeLen))

            if (writeLen)
            {
                var stream = MiNetServer.MemoryStreamManager.GetStream();
                WriteLength(stream, length);
                stream.Write(input, offset, length);
                batch.payload = stream.ToArray();
            }
            else
            {
                byte[] target = new byte[length];
                Buffer.BlockCopy(input, offset, target, 0, length);
                batch.payload = target;
            }

            batch.Encode();
            return(batch);
        }
Пример #19
0
        public McpeBatch GenerateChunk(ChunkCoordinates chunkPosition)
        {
            if (_worldProvider == null)
            {
                return(null);
            }

            ChunkColumn chunkColumn = _worldProvider.GenerateChunkColumn(chunkPosition);

            if (chunkColumn == null)
            {
                return(null);
            }

            McpeBatch chunk = chunkColumn.GetBatch();

            if (chunk == null)
            {
                return(null);
            }

            return(chunk);
        }
Пример #20
0
        public object Clone()
        {
            ChunkColumn cc = (ChunkColumn)MemberwiseClone();

            cc.chunks = new Chunk[16];
            for (int i = 0; i < chunks.Length; i++)
            {
                cc.chunks[i] = (Chunk)chunks[i].Clone();
            }

            cc.biomeId    = (byte[])biomeId.Clone();
            cc.biomeColor = (int[])biomeColor.Clone();
            cc.height     = (byte[])height.Clone();

            cc.BlockEntities = new Dictionary <BlockCoordinates, NbtCompound>();
            foreach (KeyValuePair <BlockCoordinates, NbtCompound> blockEntityPair in BlockEntities)
            {
                cc.BlockEntities.Add(blockEntityPair.Key, (NbtCompound)blockEntityPair.Value.Clone());
            }

            if (_cache != null)
            {
                cc._cache = (byte[])_cache.Clone();
            }

            McpeBatch batch = McpeBatch.CreateObject();

            batch.payload = _cachedBatch.payload;
            batch.Encode();
            batch.MarkPermanent();

            cc._cachedBatch = batch;

            _cacheSync = new object();

            return(cc);
        }
Пример #21
0
        /// <summary>
        ///     Processes a message.
        /// </summary>
        /// <param name="receiveBytes">The received bytes.</param>
        /// <param name="senderEndpoint">The sender's endpoint.</param>
        /// <exception cref="System.Exception">Receive ERROR, NAK in wrong place</exception>
        private void ProcessMessage(byte[] receiveBytes, IPEndPoint senderEndpoint)
        {
            byte msgId = receiveBytes[0];

            if (msgId == 0xFE)
            {
                Log.WarnFormat("A query detected from: {0}", senderEndpoint.Address);
                HandleQuery(receiveBytes, senderEndpoint);
            }
            else if (msgId <= (byte)DefaultMessageIdTypes.ID_USER_PACKET_ENUM)
            {
                DefaultMessageIdTypes msgIdType = (DefaultMessageIdTypes)msgId;

                Package message = PackageFactory.CreatePackage(msgId, receiveBytes);

                TraceReceive(message);

                switch (msgIdType)
                {
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING:
                case DefaultMessageIdTypes.ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
                {
                    UnconnectedPing incoming = (UnconnectedPing)message;

                    //TODO: This needs to be verified with RakNet first
                    //response.sendpingtime = msg.sendpingtime;
                    //response.sendpongtime = DateTimeOffset.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;

                    var packet = new UnconnectedPong
                    {
                        serverId   = 22345,
                        pingId     = incoming.pingId /*incoming.pingId*/,
                        serverName = string.Format(@"MCPE;{0};27;0.11.1;{1};{2}", Motd, _playerSessions.Count, 1000)
                    };
                    var data = packet.Encode();
                    TraceSend(packet);
                    SendData(data, senderEndpoint, _listener);
                    break;
                }

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_1:
                {
                    OpenConnectionRequest1 incoming = (OpenConnectionRequest1)message;

                    _isPerformanceTest = _isPerformanceTest || incoming.raknetProtocolVersion == byte.MaxValue;

                    var packet = new OpenConnectionReply1
                    {
                        serverGuid        = 12345,
                        mtuSize           = incoming.mtuSize,
                        serverHasSecurity = 0
                    };

                    var data = packet.Encode();
                    TraceSend(packet);
                    SendData(data, senderEndpoint, _listener);
                    break;
                }

                case DefaultMessageIdTypes.ID_OPEN_CONNECTION_REQUEST_2:
                {
                    OpenConnectionRequest2 incoming = (OpenConnectionRequest2)message;

                    Log.WarnFormat("New connection from: {0} {1}", senderEndpoint.Address, incoming.clientUdpPort);

                    var packet = new OpenConnectionReply2
                    {
                        serverGuid             = 12345,
                        mtuSize                = incoming.mtuSize,
                        doSecurityAndHandshake = new byte[0]
                    };

                    PlayerNetworkSession session = null;
                    lock (_playerSessions)
                    {
                        if (_playerSessions.ContainsKey(senderEndpoint))
                        {
                            PlayerNetworkSession value;
                            _playerSessions.TryRemove(senderEndpoint, out value);
                            value.Player.HandleDisconnectionNotification();
                            Log.Info("Removed ghost");
                        }

                        session = new PlayerNetworkSession(new Player(this, senderEndpoint, _levels[_random.Next(0, _levels.Count)], _pluginManager, incoming.mtuSize), senderEndpoint);
                        session.LastUpdatedTime = DateTime.UtcNow;
                        session.Mtuize          = incoming.mtuSize;

                        _playerSessions.TryAdd(senderEndpoint, session);
                    }

                    var data = packet.Encode();
                    TraceSend(packet);
                    SendData(data, senderEndpoint, session.SyncRoot);
                    break;
                }

                default:
                    Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) from {1}", msgId, senderEndpoint.Address);
                    break;
                }

                if (message != null)
                {
                    message.PutPool();
                }
                else
                {
                    Log.ErrorFormat("Receive unexpected packet with ID: {0} (0x{0:x2}) from {1}", msgId, senderEndpoint.Address);
                }
            }
            else
            {
                DatagramHeader header = new DatagramHeader(receiveBytes[0]);
                if (!header.isACK && !header.isNAK && header.isValid)
                {
                    if (receiveBytes[0] == 0xa0)
                    {
                        throw new Exception("Receive ERROR, NAK in wrong place");
                    }

                    ConnectedPackage package = ConnectedPackage.CreateObject();
                    package.Decode(receiveBytes);
                    List <Package> messages = package.Messages;

                    if (messages.Count == 1)
                    {
                        McpeBatch batch = messages.First() as McpeBatch;
                        if (batch != null)
                        {
                            messages = new List <Package>();

                            // Get bytes
                            byte[] payload = batch.payload;
                            // Decompress bytes

                            MemoryStream stream = new MemoryStream(payload);
                            if (stream.ReadByte() != 0x78)
                            {
                                throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                            }
                            stream.ReadByte();
                            using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                            {
                                // Get actual package out of bytes
                                MemoryStream destination = new MemoryStream();
                                defStream2.CopyTo(destination);
                                byte[] internalBuffer = destination.ToArray();
                                messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                            }
                        }
                    }

                    // IF reliable code below is enabled, useItem start sending doubles
                    // for some unknown reason.

                    //Reliability reliability = package._reliability;
                    //if (reliability == Reliability.Reliable
                    //	|| reliability == Reliability.ReliableSequenced
                    //	|| reliability == Reliability.ReliableOrdered
                    //	)
                    {
                        EnqueueAck(senderEndpoint, package._datagramSequenceNumber);
                    }

                    PlayerNetworkSession playerSession;
                    if (_playerSessions.TryGetValue(senderEndpoint, out playerSession))
                    {
                        foreach (var message in messages)
                        {
                            if (message is SplitPartPackage)
                            {
                                SplitPartPackage splitMessage = message as SplitPartPackage;

                                int spId    = package._splitPacketId;
                                int spIdx   = package._splitPacketIndex;
                                int spCount = package._splitPacketCount;

                                if (!playerSession.Splits.ContainsKey(spId))
                                {
                                    playerSession.Splits.Add(spId, new SplitPartPackage[spCount]);
                                }

                                SplitPartPackage[] spPackets = playerSession.Splits[spId];
                                spPackets[spIdx] = splitMessage;

                                bool haveEmpty = false;
                                for (int i = 0; i < spPackets.Length; i++)
                                {
                                    haveEmpty = haveEmpty || spPackets[i] == null;
                                }

                                if (!haveEmpty)
                                {
                                    Log.DebugFormat("Got all {0} split packages for split ID: {1}", spCount, spId);

                                    MemoryStream stream = new MemoryStream();
                                    for (int i = 0; i < spPackets.Length; i++)
                                    {
                                        byte[] buf = spPackets[i].Message;
                                        stream.Write(buf, 0, buf.Length);
                                    }

                                    byte[] buffer      = stream.ToArray();
                                    var    fullMessage = PackageFactory.CreatePackage(buffer[0], buffer) ?? new UnknownPackage(buffer[0], buffer);
                                    HandlePackage(fullMessage, playerSession);
                                }
                                continue;
                            }

                            message.Timer.Restart();
                            HandlePackage(message, playerSession);
                            message.PutPool();
                        }
                    }

                    package.PutPool();
                }
                else if (header.isACK && header.isValid)
                {
                    HandleAck(receiveBytes, senderEndpoint);
                }
                else if (header.isNAK && header.isValid)
                {
                    HandleNak(receiveBytes, senderEndpoint);
                }
                else if (!header.isValid)
                {
                    Log.Warn("!!!! ERROR, Invalid header !!!!!");
                }
            }
        }
Пример #22
0
        public IEnumerable <McpeBatch> GenerateChunks(ChunkCoordinates chunkPosition, Dictionary <Tuple <int, int>, McpeBatch> chunksUsed)
        {
            lock (chunksUsed)
            {
                Dictionary <Tuple <int, int>, double> newOrders = new Dictionary <Tuple <int, int>, double>();
                // ViewDistance is actually ViewArea
                // A = pi r^2
                // sqrt(A/pi) = r
                double radiusSquared = ViewDistance / Math.PI;
                double radius        = Math.Ceiling(Math.Sqrt(radiusSquared));
                int    centerX       = chunkPosition.X;
                int    centerZ       = chunkPosition.Z;

                for (double x = -radius; x <= radius; ++x)
                {
                    for (double z = -radius; z <= radius; ++z)
                    {
                        var distance = (x * x) + (z * z);
                        if (distance > radiusSquared)
                        {
                            continue;
                        }
                        int chunkX             = (int)(x + centerX);
                        int chunkZ             = (int)(z + centerZ);
                        Tuple <int, int> index = new Tuple <int, int>(chunkX, chunkZ);
                        newOrders[index] = distance;
                    }
                }

                if (newOrders.Count > ViewDistance)
                {
                    foreach (var pair in newOrders.OrderByDescending(pair => pair.Value))
                    {
                        if (newOrders.Count <= ViewDistance)
                        {
                            break;
                        }
                        newOrders.Remove(pair.Key);
                    }
                }

                foreach (var chunkKey in chunksUsed.Keys.ToArray())
                {
                    if (!newOrders.ContainsKey(chunkKey))
                    {
                        chunksUsed.Remove(chunkKey);
                    }
                }

                foreach (var pair in newOrders.OrderBy(pair => pair.Value))
                {
                    if (chunksUsed.ContainsKey(pair.Key))
                    {
                        continue;
                    }

                    if (_worldProvider == null)
                    {
                        continue;
                    }

                    ChunkColumn chunkColumn = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(pair.Key.Item1, pair.Key.Item2));
                    McpeBatch   chunk       = null;
                    if (chunkColumn != null)
                    {
                        chunk = chunkColumn.GetBatch();
                    }

                    chunksUsed.Add(pair.Key, chunk);

                    yield return(chunk);
                }

                if (chunksUsed.Count > ViewDistance)
                {
                    Debug.WriteLine("Too many chunks used: {0}", chunksUsed.Count);
                }
            }
        }
Пример #23
0
        /// <summary>
        ///     Handles the specified package.
        /// </summary>
        /// <param name="message">The package.</param>
        /// <param name="senderEndpoint">The sender's endpoint.</param>
        private void HandlePackage(Package message, IPEndPoint senderEndpoint)
        {
            if (typeof(McpeBatch) == message.GetType())
            {
                McpeBatch batch = (McpeBatch)message;

                var messages = new List <Package>();

                // Get bytes
                byte[] payload = batch.payload;
                // Decompress bytes

                MemoryStream stream = new MemoryStream(payload);
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                }
                stream.ReadByte();
                using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    // Get actual package out of bytes
                    MemoryStream destination = new MemoryStream();
                    defStream2.CopyTo(destination);
                    byte[] internalBuffer = destination.ToArray();
                    messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                }
                foreach (var msg in messages)
                {
                    HandlePackage(msg, senderEndpoint);
                }
                return;
            }

            TraceReceive(message);

            if (typeof(UnknownPackage) == message.GetType())
            {
                return;
            }

            if (typeof(McpeDisconnect) == message.GetType())
            {
                McpeDisconnect msg = (McpeDisconnect)message;
                Log.Debug(msg.message);
                StopServer();
                return;
            }

            if (typeof(ConnectedPing) == message.GetType())
            {
                ConnectedPing msg = (ConnectedPing)message;
                SendConnectedPong(msg.sendpingtime);
                return;
            }

            if (typeof(McpeFullChunkData) == message.GetType())
            {
                McpeFullChunkData msg   = (McpeFullChunkData)message;
                ChunkColumn       chunk = ClientUtils.DecocedChunkColumn(msg.chunkData);
                if (chunk != null)
                {
                    Log.DebugFormat("Chunk X={0}", chunk.x);
                    Log.DebugFormat("Chunk Z={0}", chunk.z);

                    ClientUtils.SaveChunkToAnvil(chunk);
                }
                return;
            }

            if (typeof(ConnectionRequestAccepted) == message.GetType())
            {
                Thread.Sleep(50);
                SendNewIncomingConnection();
                var t1 = new Timer(state => SendConnectedPing(), null, 2000, 5000);
                Thread.Sleep(50);
                SendLogin("Client12");
                return;
            }

            if (typeof(McpeSetSpawnPosition) == message.GetType())
            {
                McpeSetSpawnPosition msg = (McpeSetSpawnPosition)message;
                _spawn        = new Vector3(msg.x, msg.y, msg.z);
                _level.SpawnX = (int)_spawn.X;
                _level.SpawnY = (int)_spawn.Y;
                _level.SpawnZ = (int)_spawn.Z;

                return;
            }

            if (typeof(McpeStartGame) == message.GetType())
            {
                McpeStartGame msg = (McpeStartGame)message;
                _entityId        = msg.entityId;
                _spawn           = new Vector3(msg.x, msg.y, msg.z);
                _level.LevelName = "Default";
                _level.Version   = 19133;
                _level.GameType  = msg.gamemode;

                ClientUtils.SaveLevel(_level);

                return;
            }

            if (typeof(McpeTileEvent) == message.GetType())
            {
                McpeTileEvent msg = (McpeTileEvent)message;
                Log.DebugFormat("X: {0}", msg.x);
                Log.DebugFormat("Y: {0}", msg.y);
                Log.DebugFormat("Z: {0}", msg.z);
                Log.DebugFormat("Case 1: {0}", msg.case1);
                Log.DebugFormat("Case 2: {0}", msg.case2);
                return;
            }
            if (typeof(McpeAddEntity) == message.GetType())
            {
                McpeAddEntity msg = (McpeAddEntity)message;
                Log.DebugFormat("Entity ID: {0}", msg.entityId);
                Log.DebugFormat("Entity Type: {0}", msg.entityType);
                Log.DebugFormat("X: {0}", msg.x);
                Log.DebugFormat("Y: {0}", msg.y);
                Log.DebugFormat("Z: {0}", msg.z);
                Log.DebugFormat("Yaw: {0}", msg.yaw);
                Log.DebugFormat("Pitch: {0}", msg.pitch);
                Log.DebugFormat("Velocity X: {0}", msg.speedX);
                Log.DebugFormat("Velocity Y: {0}", msg.speedY);
                Log.DebugFormat("Velocity Z: {0}", msg.speedZ);
                Log.DebugFormat("Metadata: {0}", msg.metadata.ToString());
                Log.DebugFormat("Links count: {0}", msg.links);

                return;
            }
            if (typeof(McpeSetEntityData) == message.GetType())
            {
                McpeSetEntityData msg = (McpeSetEntityData)message;
                Log.DebugFormat("Entity ID: {0}", msg.entityId);
                MetadataDictionary metadata = msg.metadata;
                Log.DebugFormat("Metadata: {0}", metadata.ToString());
                return;
            }

            if (typeof(McpeMovePlayer) == message.GetType())
            {
                McpeMovePlayer msg = (McpeMovePlayer)message;
                Log.DebugFormat("Entity ID: {0}", msg.entityId);

                _currentLocation = new PlayerLocation(msg.x, msg.y + 10, msg.z);
                SendMcpeMovePlayer();
                return;
            }

            if (typeof(McpeUpdateBlock) == message.GetType())
            {
                McpeUpdateBlock msg = (McpeUpdateBlock)message;
                Log.DebugFormat("No of Blocks: {0}", msg.blocks.Count);
                return;
            }

            if (typeof(McpeLevelEvent) == message.GetType())
            {
                McpeLevelEvent msg = (McpeLevelEvent)message;
                Log.DebugFormat("Event ID: {0}", msg.eventId);
                Log.DebugFormat("X: {0}", msg.x);
                Log.DebugFormat("Y: {0}", msg.y);
                Log.DebugFormat("Z: {0}", msg.z);
                Log.DebugFormat("Data: {0}", msg.data);
                return;
            }
        }
Пример #24
0
        public void SpawnToAll(Player newPlayer)
        {
            lock (_playerWriteLock)
            {
                List <Player> spawnedPlayers = GetSpawnedPlayers().ToList();
                spawnedPlayers.Add(newPlayer);

                Player[] sendList = spawnedPlayers.ToArray();

                McpePlayerList playerListMessage = McpePlayerList.CreateObject();
                playerListMessage.records = new PlayerAddRecords(spawnedPlayers);
                var bytes = playerListMessage.Encode();
                playerListMessage.records = null;

                MemoryStream memStream = new MemoryStream();
                memStream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                memStream.Write(bytes, 0, bytes.Length);

                McpeBatch batch  = McpeBatch.CreateObject();
                byte[]    buffer = Player.CompressBytes(memStream.ToArray(), CompressionLevel.Optimal);
                batch.payloadSize = buffer.Length;
                batch.payload     = buffer;
                batch.Encode();

                newPlayer.SendPackage(batch);

                McpePlayerList playerList = McpePlayerList.CreateObject();
                playerList.records = new PlayerAddRecords {
                    newPlayer
                };
                playerList.Encode();
                playerList.records = null;
                RelayBroadcast(newPlayer, sendList, playerList);

                McpeAddPlayer mcpeAddPlayer = McpeAddPlayer.CreateObject();
                mcpeAddPlayer.uuid     = newPlayer.ClientUuid;
                mcpeAddPlayer.username = newPlayer.Username;
                mcpeAddPlayer.entityId = newPlayer.EntityId;
                mcpeAddPlayer.x        = newPlayer.KnownPosition.X;
                mcpeAddPlayer.y        = newPlayer.KnownPosition.Y;
                mcpeAddPlayer.z        = newPlayer.KnownPosition.Z;
                mcpeAddPlayer.yaw      = newPlayer.KnownPosition.Yaw;
                mcpeAddPlayer.headYaw  = newPlayer.KnownPosition.HeadYaw;
                mcpeAddPlayer.pitch    = newPlayer.KnownPosition.Pitch;
                mcpeAddPlayer.metadata = newPlayer.GetMetadata();
                RelayBroadcast(newPlayer, sendList, mcpeAddPlayer);

                McpePlayerEquipment mcpePlayerEquipment = McpePlayerEquipment.CreateObject();
                mcpePlayerEquipment.entityId = newPlayer.EntityId;
                mcpePlayerEquipment.item     = new MetadataSlot(newPlayer.Inventory.GetItemInHand());
                mcpePlayerEquipment.slot     = 0;
                RelayBroadcast(newPlayer, sendList, mcpePlayerEquipment);

                McpePlayerArmorEquipment mcpePlayerArmorEquipment = McpePlayerArmorEquipment.CreateObject();
                mcpePlayerArmorEquipment.entityId   = newPlayer.EntityId;
                mcpePlayerArmorEquipment.helmet     = new MetadataSlot(new ItemStack(newPlayer.Inventory.Helmet, 0));
                mcpePlayerArmorEquipment.chestplate = new MetadataSlot(new ItemStack(newPlayer.Inventory.Chest, 0));
                mcpePlayerArmorEquipment.leggings   = new MetadataSlot(new ItemStack(newPlayer.Inventory.Leggings, 0));
                mcpePlayerArmorEquipment.boots      = new MetadataSlot(new ItemStack(newPlayer.Inventory.Boots, 0));
                RelayBroadcast(newPlayer, sendList, mcpePlayerArmorEquipment);

                foreach (Player spawnedPlayer in spawnedPlayers)
                {
                    SendAddForPlayer(newPlayer, spawnedPlayer, false);
                }
            }
        }
Пример #25
0
        internal void HandlePackage(Package message, PlayerNetworkSession playerSession)
        {
            if (message == null)
            {
                return;
            }

            if (typeof(McpeWrapper) == message.GetType())
            {
                McpeWrapper wrapper = (McpeWrapper)message;

                // Get bytes
                byte[] payload = wrapper.payload;
                if (playerSession.CryptoContext != null && playerSession.CryptoContext.UseEncryption)
                {
                    payload = CryptoUtils.Decrypt(payload, playerSession.CryptoContext);
                }

                //if (Log.IsDebugEnabled)
                //	Log.Debug($"0x{payload[0]:x2}\n{Package.HexDump(payload)}");

                var msg = PackageFactory.CreatePackage(payload[0], payload, "mcpe") ?? new UnknownPackage(payload[0], payload);
                msg.DatagramSequenceNumber = wrapper.DatagramSequenceNumber;
                msg.Reliability            = wrapper.Reliability;
                msg.ReliableMessageNumber  = wrapper.ReliableMessageNumber;
                msg.OrderingChannel        = wrapper.OrderingChannel;
                msg.OrderingIndex          = wrapper.OrderingIndex;
                HandlePackage(msg, playerSession);

                message.PutPool();
                return;
            }

            if (typeof(UnknownPackage) == message.GetType())
            {
                UnknownPackage packet = (UnknownPackage)message;
                if (Log.IsDebugEnabled)
                {
                    Log.Warn($"Received unknown package 0x{message.Id:X2}\n{Package.HexDump(packet.Message)}");
                }

                message.PutPool();
                return;
            }

            if (typeof(McpeBatch) == message.GetType())
            {
                McpeBatch batch = (McpeBatch)message;

                var messages = new List <Package>();

                // Get bytes
                byte[] payload = batch.payload;
                // Decompress bytes

                MemoryStream stream = new MemoryStream(payload);
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                }
                stream.ReadByte();
                using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    // Get actual package out of bytes
                    using (MemoryStream destination = MiNetServer.MemoryStreamManager.GetStream())
                    {
                        defStream2.CopyTo(destination);
                        destination.Position = 0;
                        NbtBinaryReader reader = new NbtBinaryReader(destination, true);

                        while (destination.Position < destination.Length)
                        {
                            //int len = reader.ReadInt32();
                            int    len            = BatchUtils.ReadLength(destination);
                            byte[] internalBuffer = reader.ReadBytes(len);

                            //if (Log.IsDebugEnabled)
                            //	Log.Debug($"0x{internalBuffer[0]:x2}\n{Package.HexDump(internalBuffer)}");

                            messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer, "mcpe") ??
                                         new UnknownPackage(internalBuffer[0], internalBuffer));
                        }

                        if (destination.Length > destination.Position)
                        {
                            throw new Exception("Have more data");
                        }
                    }
                }
                foreach (var msg in messages)
                {
                    msg.DatagramSequenceNumber = batch.DatagramSequenceNumber;
                    msg.Reliability            = batch.Reliability;
                    msg.ReliableMessageNumber  = batch.ReliableMessageNumber;
                    msg.OrderingChannel        = batch.OrderingChannel;
                    msg.OrderingIndex          = batch.OrderingIndex;
                    HandlePackage(msg, playerSession);
                }

                message.PutPool();
                return;
            }

            MiNetServer.TraceReceive(message);

            if (CryptoContext != null && CryptoContext.UseEncryption)
            {
                MiNetServer.FastThreadPool.QueueUserWorkItem(delegate()
                {
                    HandlePackage(MessageHandler, message as Package);
                    message.PutPool();
                });
            }
            else
            {
                HandlePackage(MessageHandler, message);
                message.PutPool();
            }
        }
Пример #26
0
        private List<Package> HandleBatch(McpeBatch batch)
        {
            var messages = new List<Package>();

            // Get bytes
            byte[] payload = batch.payload.Array;
            // Decompress bytes

            Console.WriteLine("Package:\n" + Package.HexDump(payload));

            MemoryStream stream = new MemoryStream(payload);
            if (stream.ReadByte() != 0x78)
            {
                throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
            }
            stream.ReadByte();
            using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
            {
                // Get actual package out of bytes
                MemoryStream destination = new MemoryStream();
                defStream2.CopyTo(destination);
                destination.Position = 0;
                NbtBinaryReader reader = new NbtBinaryReader(destination, true);
                int len = reader.ReadInt32();
                byte[] internalBuffer = reader.ReadBytes(len);

                Console.WriteLine($"Package [len={len}:\n" + Package.HexDump(internalBuffer));

                messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer, "mcpe") ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                if (destination.Length > destination.Position) throw new Exception("Have more data");
            }

            return messages;
        }
Пример #27
0
        /// <summary>
        ///     Handles the specified package.
        /// </summary>
        /// <param name="message">The package.</param>
        /// <param name="senderEndpoint">The sender's endpoint.</param>
        private void HandlePackage(Package message, IPEndPoint senderEndpoint)
        {
            if (typeof(McpeBatch) == message.GetType())
            {
                Log.Debug("Processing Batch package");
                McpeBatch batch = (McpeBatch)message;

                var messages = new List <Package>();

                // Get bytes
                byte[] payload = batch.payload;
                // Decompress bytes

                MemoryStream stream = new MemoryStream(payload);
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78");
                }
                stream.ReadByte();
                using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    // Get actual package out of bytes
                    MemoryStream destination = new MemoryStream();
                    defStream2.CopyTo(destination);
                    destination.Position = 0;
                    NbtBinaryReader reader = new NbtBinaryReader(destination, true);
                    do
                    {
                        int    len            = reader.ReadInt32();
                        byte[] internalBuffer = reader.ReadBytes(len);
                        messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                    } while (destination.Position < destination.Length);                     // throw new Exception("Have more data");
                }
                foreach (var msg in messages)
                {
                    HandlePackage(msg, senderEndpoint);
                    msg.PutPool();
                }
                return;
            }

            TraceReceive(message);

            if (typeof(UnknownPackage) == message.GetType())
            {
                return;
            }

            if (typeof(McpeDisconnect) == message.GetType())
            {
                McpeDisconnect msg = (McpeDisconnect)message;
                Log.InfoFormat("Disconnect {1}: {0}", msg.message, Username);
                SendDisconnectionNotification();
                StopClient();
                return;
            }

            if (typeof(ConnectedPing) == message.GetType())
            {
                ConnectedPing msg = (ConnectedPing)message;
                SendConnectedPong(msg.sendpingtime);
                return;
            }

            if (typeof(McpeFullChunkData) == message.GetType())
            {
                //McpeFullChunkData msg = (McpeFullChunkData) message;
                //ChunkColumn chunk = ClientUtils.DecocedChunkColumn(msg.chunkData);
                //if (chunk != null)
                //{
                //	Log.DebugFormat("Chunk X={0}", chunk.x);
                //	Log.DebugFormat("Chunk Z={0}", chunk.z);

                //	//ClientUtils.SaveChunkToAnvil(chunk);
                //}
                return;
            }

            if (typeof(ConnectionRequestAccepted) == message.GetType())
            {
                Thread.Sleep(50);
                SendNewIncomingConnection();
                //_connectedPingTimer = new Timer(state => SendConnectedPing(), null, 1000, 1000);
                Thread.Sleep(50);
                SendLogin(Username);
                return;
            }

            if (typeof(McpeSetSpawnPosition) == message.GetType())
            {
                McpeSetSpawnPosition msg = (McpeSetSpawnPosition)message;
                _spawn        = new Vector3(msg.x, msg.y, msg.z);
                _level.SpawnX = (int)_spawn.X;
                _level.SpawnY = (int)_spawn.Y;
                _level.SpawnZ = (int)_spawn.Z;

                return;
            }

            if (typeof(McpeStartGame) == message.GetType())
            {
                McpeStartGame msg = (McpeStartGame)message;
                _entityId        = msg.entityId;
                _spawn           = new Vector3(msg.x, msg.y, msg.z);
                _level.LevelName = "Default";
                _level.Version   = 19133;
                _level.GameType  = msg.gamemode;

                //ClientUtils.SaveLevel(_level);

                return;
            }

            if (typeof(McpeTileEvent) == message.GetType())
            {
                McpeTileEvent msg = (McpeTileEvent)message;
                Log.DebugFormat("X: {0}", msg.x);
                Log.DebugFormat("Y: {0}", msg.y);
                Log.DebugFormat("Z: {0}", msg.z);
                Log.DebugFormat("Case 1: {0}", msg.case1);
                Log.DebugFormat("Case 2: {0}", msg.case2);
                return;
            }
            if (typeof(McpeAddEntity) == message.GetType())
            {
                McpeAddEntity msg = (McpeAddEntity)message;
                Log.DebugFormat("Entity ID: {0}", msg.entityId);
                Log.DebugFormat("Entity Type: {0}", msg.entityType);
                Log.DebugFormat("X: {0}", msg.x);
                Log.DebugFormat("Y: {0}", msg.y);
                Log.DebugFormat("Z: {0}", msg.z);
                Log.DebugFormat("Yaw: {0}", msg.yaw);
                Log.DebugFormat("Pitch: {0}", msg.pitch);
                Log.DebugFormat("Velocity X: {0}", msg.speedX);
                Log.DebugFormat("Velocity Y: {0}", msg.speedY);
                Log.DebugFormat("Velocity Z: {0}", msg.speedZ);
                //Log.DebugFormat("Metadata: {0}", msg.metadata.ToString());
                //Log.DebugFormat("Links count: {0}", msg.links);

                return;
            }
            if (typeof(McpeSetEntityData) == message.GetType())
            {
                McpeSetEntityData msg = (McpeSetEntityData)message;
                Log.DebugFormat("Entity ID: {0}", msg.entityId);
                MetadataDictionary metadata = msg.metadata;
                Log.DebugFormat("Metadata: {0}", metadata.ToString());
                return;
            }

            if (typeof(McpeMovePlayer) == message.GetType())
            {
                //McpeMovePlayer msg = (McpeMovePlayer) message;
                //Log.DebugFormat("Entity ID: {0}", msg.entityId);

                //CurrentLocation = new PlayerLocation(msg.x, msg.y + 10, msg.z);
                //SendMcpeMovePlayer();
                return;
            }

            if (typeof(McpeUpdateBlock) == message.GetType())
            {
                McpeUpdateBlock msg = (McpeUpdateBlock)message;
                Log.DebugFormat("No of Blocks: {0}", msg.blocks.Count);
                return;
            }

            if (typeof(McpeLevelEvent) == message.GetType())
            {
                McpeLevelEvent msg = (McpeLevelEvent)message;
                Log.DebugFormat("Event ID: {0}", msg.eventId);
                Log.DebugFormat("X: {0}", msg.x);
                Log.DebugFormat("Y: {0}", msg.y);
                Log.DebugFormat("Z: {0}", msg.z);
                Log.DebugFormat("Data: {0}", msg.data);
                return;
            }

            if (typeof(McpeContainerSetContent) == message.GetType())
            {
                McpeContainerSetContent msg = (McpeContainerSetContent)message;
                Log.DebugFormat("Window ID: 0x{0:x2}, Count: {1}", msg.windowId, msg.slotData.Count);
                var slots = msg.slotData.GetValues();

                foreach (var entry in slots)
                {
                    MetadataSlot slot = (MetadataSlot)entry;
                    //Log.DebugFormat(" - Id: {0}, Metadata: {1}, Count: {2}", slot.Value.Item.Id, slot.Value.Item.Metadata, slot.Value.Count);
                }
                return;
            }

            if (typeof(McpeCraftingData) == message.GetType())
            {
                string fileName = Path.GetTempPath() + "Recipes_" + Guid.NewGuid() + ".txt";
                Log.Info("Writing recipes to filename: " + fileName);
                FileStream file = File.OpenWrite(fileName);

                McpeCraftingData   msg    = (McpeCraftingData)message;
                IndentedTextWriter writer = new IndentedTextWriter(new StreamWriter(file));

                writer.WriteLine("static RecipeManager()");
                writer.WriteLine("{");
                writer.Indent++;
                writer.WriteLine("Recipes = new Recipes");
                writer.WriteLine("{");
                writer.Indent++;

                foreach (Recipe recipe in msg.recipes)
                {
                    ShapelessRecipe shapelessRecipe = recipe as ShapelessRecipe;
                    if (shapelessRecipe != null)
                    {
                        writer.WriteLine(string.Format("new ShapelessRecipe(new ItemStack(ItemFactory.GetItem({0}, {1}), {2}),", shapelessRecipe.Result.Id, shapelessRecipe.Result.Metadata, shapelessRecipe.Result.Count));
                        writer.Indent++;
                        writer.WriteLine("new List<ItemStack>");
                        writer.WriteLine("{");
                        writer.Indent++;
                        foreach (var itemStack in shapelessRecipe.Input)
                        {
                            writer.WriteLine(string.Format("new ItemStack(ItemFactory.GetItem({0}, {1}), {2}),", itemStack.Id, itemStack.Metadata, itemStack.Count));
                        }
                        writer.Indent--;
                        writer.WriteLine("}),");
                        writer.Indent--;

                        continue;
                    }

                    ShapedRecipe shapedRecipe = recipe as ShapedRecipe;
                    if (shapedRecipe != null)
                    {
                        writer.WriteLine(string.Format("new ShapedRecipe({0}, {1}, new ItemStack(ItemFactory.GetItem({2}, {3}), {4}),", shapedRecipe.Width, shapedRecipe.Height, shapedRecipe.Result.Id, shapedRecipe.Result.Metadata, shapedRecipe.Result.Count));
                        writer.Indent++;
                        writer.WriteLine("new Item[]");
                        writer.WriteLine("{");
                        writer.Indent++;
                        foreach (Item item in shapedRecipe.Input)
                        {
                            writer.WriteLine(string.Format("ItemFactory.GetItem({0}, {1}),", item.Id, item.Metadata));
                        }
                        writer.Indent--;
                        writer.WriteLine("}),");
                        writer.Indent--;

                        continue;
                    }
                }

                writer.WriteLine("};");
                writer.Indent--;
                writer.WriteLine("}");
                writer.Indent--;

                writer.Flush();

                file.Close();
                Environment.Exit(0);
                return;
            }
        }
Пример #28
0
        protected virtual void BroadCastMovement(Player[] players, Entity[] entities)
        {
            if (players.Length == 0)
            {
                return;
            }

            DateTime tickTime = _lastSendTime;

            _lastSendTime = DateTime.UtcNow;
            DateTime now = DateTime.UtcNow;

            MemoryStream stream = MiNetServer.MemoryStreamManager.GetStream();

            int            count = 0;
            McpeMovePlayer move  = McpeMovePlayer.CreateObject();

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

                    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();
                    stream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                    stream.Write(bytes, 0, bytes.Length);
                    move.Reset();
                    count++;
                }
            }
            move.PutPool();

            McpeMoveEntity moveEntity = McpeMoveEntity.CreateObject();

            moveEntity.entities = new EntityLocations();

            McpeSetEntityMotion entityMotion = McpeSetEntityMotion.CreateObject();

            entityMotion.entities = new EntityMotions();

            foreach (var entity in entities)
            {
                if (((now - entity.LastUpdatedTime) <= now - tickTime))
                {
                    moveEntity.entities.Add(entity.EntityId, entity.KnownPosition);
                    entityMotion.entities.Add(entity.EntityId, entity.Velocity);
                    count++;
                }
            }

            if (moveEntity.entities.Count > 0)
            {
                byte[] bytes = moveEntity.Encode();
                stream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                stream.Write(bytes, 0, bytes.Length);
            }
            moveEntity.PutPool();

            if (moveEntity.entities.Count > 0)
            {
                byte[] bytes = entityMotion.Encode();
                stream.Write(BitConverter.GetBytes(Endian.SwapInt32(bytes.Length)), 0, 4);
                stream.Write(bytes, 0, bytes.Length);
            }
            entityMotion.PutPool();

            if (count == 0)
            {
                return;
            }

            McpeBatch batch = McpeBatch.CreateObject(players.Length);

            byte[] buffer = Player.CompressBytes(stream.ToArray(), CompressionLevel.Optimal);
            batch.payloadSize = buffer.Length;
            batch.payload     = buffer;
            batch.Encode(true);

            foreach (var player in players)
            {
                Task sendTask = new Task(obj => ((Player)obj).SendMoveList(batch, now), player);
                sendTask.Start();
            }
        }
Пример #29
0
        public void SendLogin(string username)
        {
            Skin skin = new Skin {Slim = false, Texture = Encoding.Default.GetBytes(new string('Z', 8192))};
            skin.SkinType = "Standard_Custom";
            //Skin skin = new Skin { Slim = false, Texture = Encoding.Default.GetBytes(new string('Z', 16384)) };
            var packet = new McpeLogin()
            {
                username = username,
                protocol = 39,
                protocol2 = 39,
                clientId = ClientId,
                clientUuid = new UUID(Guid.NewGuid().ToByteArray()),
                serverAddress = _serverEndpoint.Address + ":" + _serverEndpoint.Port,
                clientSecret = "iwmvi45hm85oncyo58",
                //clientSecret = Encoding.ASCII.GetString(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("" + ClientId + _serverEndpoint.Address + _serverEndpoint.Port))),
                skin = skin,
            };

            byte[] buffer = Player.CompressBytes(packet.Encode(), CompressionLevel.Fastest, true);

            McpeBatch batch = new McpeBatch();
            batch.payloadSize = buffer.Length;
            batch.payload = buffer;
            batch.Encode();

            SendPackage(batch);
            LoginSent = true;
        }
Пример #30
0
		public void SendMoveList(McpeBatch batch, DateTime sendTime)
		{
			if (sendTime < _lastMoveListSendTime || !Monitor.TryEnter(_sendMoveListSync))
			{
				batch.PutPool();
				return;
			}

			_lastMoveListSendTime = sendTime;

			try
			{
				//Server.SendPackage(this, batch, _mtuSize, ref _reliableMessageNumber);
				SendPackage(batch);
			}
			finally
			{
				Monitor.Exit(_sendMoveListSync);
			}
		}
Пример #31
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;
            }
        }
Пример #32
0
        public void SendLogin(string username)
        {
            Skin skin = new Skin {Slim = false, Texture = Encoding.Default.GetBytes(new string('Z', 8192))};
            var packet = new McpeLogin()
            {
                clientId = 12345,
                username = username,
                protocol = 27,
                skin = skin
            };

            McpeBatch batch = new McpeBatch();
            byte[] buffer = CompressBytes(packet.Encode());

            batch.payloadSize = buffer.Length;
            batch.payload = buffer;

            SendPackage(batch);
        }
Пример #33
0
        public IEnumerable <McpeBatch> GenerateChunks(ChunkCoordinates chunkPosition, Dictionary <Tuple <int, int>, McpeBatch> chunksUsed, double radius)
        {
            lock (chunksUsed)
            {
                Dictionary <Tuple <int, int>, double> newOrders = new Dictionary <Tuple <int, int>, double>();

                double radiusSquared = Math.Pow(radius, 2);

                int centerX = chunkPosition.X;
                int centerZ = chunkPosition.Z;

                for (double x = -radius; x <= radius; ++x)
                {
                    for (double z = -radius; z <= radius; ++z)
                    {
                        var distance = (x * x) + (z * z);
                        if (distance > radiusSquared)
                        {
                            //continue;
                        }
                        int chunkX             = (int)(x + centerX);
                        int chunkZ             = (int)(z + centerZ);
                        Tuple <int, int> index = new Tuple <int, int>(chunkX, chunkZ);
                        newOrders[index] = distance;
                    }
                }

                //if (newOrders.Count > viewArea)
                //{
                //	foreach (var pair in newOrders.OrderByDescending(pair => pair.Value))
                //	{
                //		if (newOrders.Count <= viewArea) break;
                //		newOrders.Remove(pair.Key);
                //	}
                //}

                foreach (var chunkKey in chunksUsed.Keys.ToArray())
                {
                    if (!newOrders.ContainsKey(chunkKey))
                    {
                        chunksUsed.Remove(chunkKey);
                    }
                }

                foreach (var pair in newOrders.OrderBy(pair => pair.Value))
                {
                    if (chunksUsed.ContainsKey(pair.Key))
                    {
                        continue;
                    }

                    if (_worldProvider == null)
                    {
                        continue;
                    }

                    ChunkColumn chunkColumn = _worldProvider.GenerateChunkColumn(new ChunkCoordinates(pair.Key.Item1, pair.Key.Item2));
                    McpeBatch   chunk       = null;
                    if (chunkColumn != null)
                    {
                        chunk = chunkColumn.GetBatch();
                    }

                    chunksUsed.Add(pair.Key, chunk);

                    yield return(chunk);
                }
            }
        }
Пример #34
0
        internal void HandlePackage(Package message, PlayerNetworkSession playerSession)
        {
            if (message == null)
            {
                return;
            }

            TraceReceive(message);

            if (typeof(UnknownPackage) == message.GetType())
            {
                UnknownPackage packet = (UnknownPackage)message;
                Log.Warn($"Received unknown package 0x{message.Id:X2}\n{Package.HexDump(packet.Message)}");
                return;
            }

            if (typeof(McpeBatch) == message.GetType())
            {
                McpeBatch batch = (McpeBatch)message;

                var messages = new List <Package>();

                // Get bytes
                byte[] payload = batch.payload;
                // Decompress bytes

                MemoryStream stream = new MemoryStream(payload);
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                }
                stream.ReadByte();
                using (var defStream2 = new DeflateStream(stream, CompressionMode.Decompress, false))
                {
                    // Get actual package out of bytes
                    MemoryStream destination = MiNetServer.MemoryStreamManager.GetStream();
                    defStream2.CopyTo(destination);
                    destination.Position = 0;
                    NbtBinaryReader reader         = new NbtBinaryReader(destination, true);
                    int             len            = reader.ReadInt32();
                    byte[]          internalBuffer = reader.ReadBytes(len);

                    //byte[] internalBuffer = destination.ToArray();
                    messages.Add(PackageFactory.CreatePackage(internalBuffer[0], internalBuffer) ?? new UnknownPackage(internalBuffer[0], internalBuffer));
                    if (destination.Length > destination.Position)
                    {
                        throw new Exception("Have more data");
                    }
                }
                foreach (var msg in messages)
                {
                    msg.DatagramSequenceNumber = batch.DatagramSequenceNumber;
                    msg.OrderingChannel        = batch.OrderingChannel;
                    msg.OrderingIndex          = batch.OrderingIndex;
                    HandlePackage(msg, playerSession);
                    msg.PutPool();
                }

                return;
            }

            Player player = playerSession.Player;

            if (player != null)
            {
                player.HandlePackage(message);
            }
        }