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; }
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 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); } }
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); } }
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); } }
internal static McpeBatch CreateMcpeBatch(byte[] bytes) { McpeBatch batch = BatchUtils.CreateBatchPacket(bytes, 0, (int)bytes.Length, CompressionLevel.Optimal, true); batch.MarkPermanent(); batch.Encode(); 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 void ClearCache() { lock (_cacheSync) { if (_cachedBatch != null) { _cachedBatch.MarkPermanent(false); _cachedBatch.PutPool(); _cachedBatch = null; } } }
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); }
/// <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); } }
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(); } }
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 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); }
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); }
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 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); }
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); }
/// <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 !!!!!"); } } }
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); } } }
/// <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; } }
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) { 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(); } }
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; }
/// <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; } }
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 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; }
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); } }
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; } }
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); }
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); } } }
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); } }