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); } }
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); }
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); }
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); } }
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); }
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); } }
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); } }
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); }
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); }
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(); } }
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); } } }
internal void HandlePackage(Package message, PlayerNetworkSession playerSession) { try { if (message == null) { return; } if (typeof(McpeWrapper) == message.GetType()) { McpeWrapper wrapper = (McpeWrapper)message; // Get bytes byte[] payload = wrapper.payload; //if (Log.IsDebugEnabled) Log.Debug($"Received package 0x{message.Id:X2}\n{Package.HexDump(payload)}"); if (playerSession.CryptoContext != null && playerSession.CryptoContext.UseEncryption) { payload = CryptoUtils.Decrypt(payload, playerSession.CryptoContext); } McpeBatch batch = McpeBatch.CreateObject(); batch.payload = payload; HandlePackage(batch, playerSession); //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(); } } catch (Exception e) { Log.Error("Package handling", e); throw; } }
private void SendQueue(object sender) { if (!IsConnected) { return; } Queue <Package> queue = _sendQueueNotConcurrent; int messageCount = 0; int lenght = queue.Count; MemoryStream stream = new MemoryStream(); for (int i = 0; i < lenght; i++) { Package package = null; lock (_queueSync) { if (queue.Count == 0) { break; } try { package = queue.Dequeue(); } catch (Exception e) { } } if (package == null) { continue; } byte[] bytes = package.Encode(); if (bytes != null) { messageCount++; stream.Write(bytes, 0, bytes.Length); package.PutPool(); } } if (messageCount == 0) { return; } 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); }
/// <summary> /// Sends the chunks for known position. /// </summary> private void SendChunksForKnownPosition() { var chunkPosition = new ChunkCoordinates(KnownPosition); if (IsSpawned && _currentChunkPosition == chunkPosition) { return; } _currentChunkPosition = chunkPosition; ThreadPool.QueueUserWorkItem(delegate(object state) { int packetCount = 0; if (!IsBot) { while (Rtt < 0) { Thread.Yield(); } } MemoryStream stream = new MemoryStream(); foreach (var chunk in Level.GenerateChunks(_currentChunkPosition, _chunksUsed)) { McpeFullChunkData fullChunkData = McpeFullChunkData.CreateObject(); fullChunkData.chunkX = chunk.x; fullChunkData.chunkZ = chunk.z; fullChunkData.chunkData = chunk.GetBytes(); fullChunkData.chunkDataLength = fullChunkData.chunkData.Length; McpeBatch batch = McpeBatch.CreateObject(); byte[] buffer = CompressBytes(fullChunkData.Encode()); batch.payloadSize = buffer.Length; batch.payload = buffer; fullChunkData.PutPool(); // This is to slow down chunk-sending not to overrun old devices. // The timeout should be configurable and enable/disable. if (Math.Floor(Rtt / 10d) > 0) { Thread.Sleep(Math.Min(Math.Max((int)Math.Floor(Rtt / 10d), 12) + 10, 40)); } SendPackage(batch, sendDirect: true); //var bytes = fullChunkData.Encode(); //stream.Write(bytes, 0, bytes.Length); if (!IsSpawned) { if (packetCount++ == 56) { InitializePlayer(); } } } //McpeBatch batch = new McpeBatch(); //byte[] buffer = CompressBytes(stream.ToArray()); //batch.payloadSize = buffer.Length; //batch.payload = buffer; //batch.Encode(); //SendPackage(batch); }); }