private int TryReadPacket() { BinaryReader br = new BinaryReader(new MemoryStream(received.ToArray())); if (received.Count == 0) { return 0; } var packetId = (MinecraftServerPacketId)br.ReadByte(); int totalread = 1; if (packetId != MinecraftServerPacketId.PositionandOrientationUpdate && packetId != MinecraftServerPacketId.PositionUpdate && packetId != MinecraftServerPacketId.OrientationUpdate && packetId != MinecraftServerPacketId.PlayerTeleport && packetId != MinecraftServerPacketId.ExtendedPacketTick) { Console.WriteLine(Enum.GetName(typeof(MinecraftServerPacketId), packetId)); } switch (packetId) { case MinecraftServerPacketId.ServerIdentification: { totalread += 1 + NetworkHelper.StringLength + NetworkHelper.StringLength + 1; if (received.Count < totalread) { return 0; } if (ENABLE_FORTRESS) { totalread += NetworkHelper.StringLength; if (received.Count < totalread) { return 0; } } ServerPlayerIdentification p = new ServerPlayerIdentification(); p.ProtocolVersion = br.ReadByte(); string invalidversionstr = "Invalid game version. Local: {0}, Server: {1}"; if (!ENABLE_FORTRESS) { if (!(p.ProtocolVersion == 7 || p.ProtocolVersion == 6)) { throw new Exception(string.Format(invalidversionstr, "Minecraft 7", "Minecraft " + p.ProtocolVersion)); } } else { string servergameversion = NetworkHelper.ReadString64(br); if (p.ProtocolVersion != 200) { servergameversion = "Minecraft " + p.ProtocolVersion; } if (servergameversion != GameVersion.Version) { throw new Exception(string.Format(invalidversionstr, GameVersion.Version, servergameversion)); } } p.ServerName = NetworkHelper.ReadString64(br); p.ServerMotd = NetworkHelper.ReadString64(br); p.UserType = br.ReadByte(); //connected = true; this.serverName = p.ServerName; this.ServerMotd = p.ServerMotd; ChatLog("---Connected---"); } break; case MinecraftServerPacketId.Ping: { } break; case MinecraftServerPacketId.LevelInitialize: { receivedMapStream = new MemoryStream(); InvokeMapLoadingProgress(0, 0); } break; case MinecraftServerPacketId.LevelDataChunk: { totalread += 2 + 1024 + 1; if (received.Count < totalread) { return 0; } int chunkLength = NetworkHelper.ReadInt16(br); byte[] chunkData = br.ReadBytes(1024); BinaryWriter bw1 = new BinaryWriter(receivedMapStream); byte[] chunkDataWithoutPadding = new byte[chunkLength]; for (int i = 0; i < chunkLength; i++) { chunkDataWithoutPadding[i] = chunkData[i]; } bw1.Write(chunkDataWithoutPadding); MapLoadingPercentComplete = br.ReadByte(); InvokeMapLoadingProgress(MapLoadingPercentComplete, (int)receivedMapStream.Length); } break; case MinecraftServerPacketId.LevelFinalize: { totalread += 2 + 2 + 2; if (received.Count < totalread) { return 0; } if (ENABLE_FORTRESS) { totalread += 4; if (received.Count < totalread) { return 0; } //simulationstartframe } mapreceivedsizex = NetworkHelper.ReadInt16(br); mapreceivedsizez = NetworkHelper.ReadInt16(br); mapreceivedsizey = NetworkHelper.ReadInt16(br); receivedMapStream.Seek(0, SeekOrigin.Begin); if (!ENABLE_FORTRESS) { MemoryStream decompressed = new MemoryStream(compression.Decompress(receivedMapStream.ToArray())); if (decompressed.Length != mapreceivedsizex * mapreceivedsizey * mapreceivedsizez + (decompressed.Length % 1024)) { //throw new Exception(); Console.WriteLine("warning: invalid map data size"); } byte[, ,] receivedmap = new byte[mapreceivedsizex, mapreceivedsizey, mapreceivedsizez]; { BinaryReader br2 = new BinaryReader(decompressed); int size = NetworkHelper.ReadInt32(br2); for (int z = 0; z < mapreceivedsizez; z++) { for (int y = 0; y < mapreceivedsizey; y++) { for (int x = 0; x < mapreceivedsizex; x++) { receivedmap[x, y, z] = br2.ReadByte(); } } } } MapStoragePortion.UseMap(receivedmap); Map.Map.MapSizeX = receivedmap.GetUpperBound(0) + 1; Map.Map.MapSizeY = receivedmap.GetUpperBound(1) + 1; Map.Map.MapSizeZ = receivedmap.GetUpperBound(2) + 1; Console.WriteLine("Game loaded successfully."); } else { int simulationstartframe = NetworkHelper.ReadInt32(br); gameworld.LoadState(receivedMapStream.ToArray(), simulationstartframe); } if (MapLoaded != null) { MapLoaded.Invoke(this, new MapLoadedEventArgs() { }); } loadedtime = DateTime.Now; } break; case MinecraftServerPacketId.SetBlock: { int x; int y; int z; if (ENABLE_FORTRESS) { throw new Exception("SetBlock packet");//no such packet. } else { totalread += 2 + 2 + 2 + 1; if (received.Count < totalread) { return 0; } x = NetworkHelper.ReadInt16(br); z = NetworkHelper.ReadInt16(br); y = NetworkHelper.ReadInt16(br); } byte type = br.ReadByte(); try { Map.SetTileAndUpdate(new Vector3(x, y, z), type); } catch { Console.WriteLine("Cannot update tile!"); } } break; case MinecraftServerPacketId.SpawnPlayer: { if (ENABLE_FORTRESS) { totalread += 1 + NetworkHelper.StringLength + 4 + 4 + 4 + 1 + 1; if (received.Count < totalread) { return 0; } } else { totalread += 1 + NetworkHelper.StringLength + 2 + 2 + 2 + 1 + 1; if (received.Count < totalread) { return 0; } } byte playerid = br.ReadByte(); string playername = NetworkHelper.ReadString64(br); if (ENABLE_FORTRESS && playerid == 255) { spawned = true; break; } connectedplayers.Add(new ConnectedPlayer() { name = playername, id = playerid }); if (Clients.Players.ContainsKey(playerid)) { //throw new Exception(); } Clients.Players[playerid] = new Player(); Clients.Players[playerid].Name = playername; if (ENABLE_FORTRESS && ((DateTime.Now - loadedtime).TotalSeconds > 10)) { ReadAndUpdatePlayerPosition(br, playerid); } if (!ENABLE_FORTRESS) { ReadAndUpdatePlayerPosition(br, playerid); } if (playerid == 255) { spawned = true; } } break; case MinecraftServerPacketId.PlayerTeleport: { if (ENABLE_FORTRESS) { totalread += 1 + (4 + 4 + 4) + 1 + 1; if (received.Count < totalread) { return 0; } } else { totalread += 1 + (2 + 2 + 2) + 1 + 1; if (received.Count < totalread) { return 0; } } byte playerid = br.ReadByte(); ReadAndUpdatePlayerPosition(br, playerid); } break; case MinecraftServerPacketId.PositionandOrientationUpdate: { totalread += 1 + (1 + 1 + 1) + 1 + 1; if (received.Count < totalread) { return 0; } byte playerid = br.ReadByte(); float x = (float)br.ReadSByte() / 32; float y = (float)br.ReadSByte() / 32; float z = (float)br.ReadSByte() / 32; byte heading = br.ReadByte(); byte pitch = br.ReadByte(); Vector3 v = new Vector3(x, y, z); UpdatePositionDiff(playerid, v); } break; case MinecraftServerPacketId.PositionUpdate: { totalread += 1 + 1 + 1 + 1; if (received.Count < totalread) { return 0; } byte playerid = br.ReadByte(); float x = (float)br.ReadSByte() / 32; float y = (float)br.ReadSByte() / 32; float z = (float)br.ReadSByte() / 32; Vector3 v = new Vector3(x, y, z); UpdatePositionDiff(playerid, v); } break; case MinecraftServerPacketId.OrientationUpdate: { totalread += 1 + 1 + 1; if (received.Count < totalread) { return 0; } byte playerid = br.ReadByte(); byte heading = br.ReadByte(); byte pitch = br.ReadByte(); Clients.Players[playerid].Heading = heading; Clients.Players[playerid].Pitch = pitch; } break; case MinecraftServerPacketId.DespawnPlayer: { totalread += 1; if (received.Count < totalread) { return 0; } byte playerid = br.ReadByte(); for (int i = 0; i < connectedplayers.Count; i++) { if (connectedplayers[i].id == playerid) { connectedplayers.RemoveAt(i); } } Clients.Players.Remove(playerid); } break; case MinecraftServerPacketId.Message: { totalread += 1 + NetworkHelper.StringLength; if (received.Count < totalread) { return 0; } byte unused = br.ReadByte(); string message = NetworkHelper.ReadString64(br); Chatlines.AddChatline(message); ChatLog(message); } break; case MinecraftServerPacketId.DisconnectPlayer: { totalread += NetworkHelper.StringLength; if (received.Count < totalread) { return 0; } string disconnectReason = NetworkHelper.ReadString64(br); throw new Exception(disconnectReason); } case MinecraftServerPacketId.ExtendedPacketCommand: { totalread += 1 + 4 + 4; if (received.Count < totalread) { return 0; } int playerid = br.ReadByte(); int cmdframe = NetworkHelper.ReadInt32(br); int length = NetworkHelper.ReadInt32(br); totalread += length; if (received.Count < totalread) { return 0; } byte[] cmd = br.ReadBytes(length); gameworld.EnqueueCommand(playerid, cmdframe, cmd); } break; case MinecraftServerPacketId.ExtendedPacketTick: { totalread += 4 + 4; if (received.Count < totalread) { return 0; } int allowedframe = NetworkHelper.ReadInt32(br); int hash = NetworkHelper.ReadInt32(br); totalread += 1; if (received.Count < totalread) { return 0; } int clientscount = br.ReadByte(); totalread += clientscount * (1 + (3 * 4) + 1 + 1); if (received.Count < totalread) { return 0; } Dictionary<int, PlayerPosition> playerpositions = new Dictionary<int, PlayerPosition>(); for (int i = 0; i < clientscount; i++) { byte playerid = br.ReadByte(); //copied float x = (float)((double)NetworkHelper.ReadInt32(br) / 32); float y = (float)((double)NetworkHelper.ReadInt32(br) / 32); float z = (float)((double)NetworkHelper.ReadInt32(br) / 32); byte heading = br.ReadByte(); byte pitch = br.ReadByte(); playerpositions[playerid] = new PlayerPosition() { position = new Vector3(x, y, z), heading = heading, pitch = pitch }; } gameworld.KeyFrame(allowedframe, hash, playerpositions); } break; default: { throw new Exception("Invalid packet id"); } } return totalread; }
private int TryReadPacket() { BinaryReader br = new BinaryReader(new MemoryStream(received.ToArray())); if (received.Count == 0) { return(0); } var packetId = (MinecraftServerPacketId)br.ReadByte(); int totalread = 1; if (packetId != MinecraftServerPacketId.PositionandOrientationUpdate && packetId != MinecraftServerPacketId.PositionUpdate && packetId != MinecraftServerPacketId.OrientationUpdate && packetId != MinecraftServerPacketId.PlayerTeleport && packetId != MinecraftServerPacketId.ExtendedPacketTick) { Console.WriteLine(Enum.GetName(typeof(MinecraftServerPacketId), packetId)); } switch (packetId) { case MinecraftServerPacketId.ServerIdentification: { totalread += 1 + NetworkHelper.StringLength + NetworkHelper.StringLength + 1; if (received.Count < totalread) { return(0); } if (ENABLE_FORTRESS) { totalread += NetworkHelper.StringLength; if (received.Count < totalread) { return(0); } } ServerPlayerIdentification p = new ServerPlayerIdentification(); p.ProtocolVersion = br.ReadByte(); string invalidversionstr = "Invalid game version. Local: {0}, Server: {1}"; if (!ENABLE_FORTRESS) { if (!(p.ProtocolVersion == 7 || p.ProtocolVersion == 6)) { throw new Exception(string.Format(invalidversionstr, "Minecraft 7", "Minecraft " + p.ProtocolVersion)); } } else { string servergameversion = NetworkHelper.ReadString64(br); if (p.ProtocolVersion != 200) { servergameversion = "Minecraft " + p.ProtocolVersion; } if (servergameversion != GameVersion.Version) { throw new Exception(string.Format(invalidversionstr, GameVersion.Version, servergameversion)); } } p.ServerName = NetworkHelper.ReadString64(br); p.ServerMotd = NetworkHelper.ReadString64(br); p.UserType = br.ReadByte(); //connected = true; this.serverName = p.ServerName; this.ServerMotd = p.ServerMotd; ChatLog("---Connected---"); } break; case MinecraftServerPacketId.Ping: { } break; case MinecraftServerPacketId.LevelInitialize: { receivedMapStream = new MemoryStream(); InvokeMapLoadingProgress(0, 0); } break; case MinecraftServerPacketId.LevelDataChunk: { totalread += 2 + 1024 + 1; if (received.Count < totalread) { return(0); } int chunkLength = NetworkHelper.ReadInt16(br); byte[] chunkData = br.ReadBytes(1024); BinaryWriter bw1 = new BinaryWriter(receivedMapStream); byte[] chunkDataWithoutPadding = new byte[chunkLength]; for (int i = 0; i < chunkLength; i++) { chunkDataWithoutPadding[i] = chunkData[i]; } bw1.Write(chunkDataWithoutPadding); MapLoadingPercentComplete = br.ReadByte(); InvokeMapLoadingProgress(MapLoadingPercentComplete, (int)receivedMapStream.Length); } break; case MinecraftServerPacketId.LevelFinalize: { totalread += 2 + 2 + 2; if (received.Count < totalread) { return(0); } if (ENABLE_FORTRESS) { totalread += 4; if (received.Count < totalread) { return(0); } //simulationstartframe } mapreceivedsizex = NetworkHelper.ReadInt16(br); mapreceivedsizez = NetworkHelper.ReadInt16(br); mapreceivedsizey = NetworkHelper.ReadInt16(br); receivedMapStream.Seek(0, SeekOrigin.Begin); if (!ENABLE_FORTRESS) { MemoryStream decompressed = new MemoryStream(compression.Decompress(receivedMapStream.ToArray())); if (decompressed.Length != mapreceivedsizex * mapreceivedsizey * mapreceivedsizez + (decompressed.Length % 1024)) { //throw new Exception(); Console.WriteLine("warning: invalid map data size"); } byte[, ,] receivedmap = new byte[mapreceivedsizex, mapreceivedsizey, mapreceivedsizez]; { BinaryReader br2 = new BinaryReader(decompressed); int size = NetworkHelper.ReadInt32(br2); for (int z = 0; z < mapreceivedsizez; z++) { for (int y = 0; y < mapreceivedsizey; y++) { for (int x = 0; x < mapreceivedsizex; x++) { receivedmap[x, y, z] = br2.ReadByte(); } } } } MapStoragePortion.UseMap(receivedmap); Map.Map.MapSizeX = receivedmap.GetUpperBound(0) + 1; Map.Map.MapSizeY = receivedmap.GetUpperBound(1) + 1; Map.Map.MapSizeZ = receivedmap.GetUpperBound(2) + 1; Console.WriteLine("Game loaded successfully."); } else { int simulationstartframe = NetworkHelper.ReadInt32(br); gameworld.LoadState(receivedMapStream.ToArray(), simulationstartframe); } if (MapLoaded != null) { MapLoaded.Invoke(this, new MapLoadedEventArgs() { }); } loadedtime = DateTime.Now; } break; case MinecraftServerPacketId.SetBlock: { int x; int y; int z; if (ENABLE_FORTRESS) { throw new Exception("SetBlock packet"); //no such packet. } else { totalread += 2 + 2 + 2 + 1; if (received.Count < totalread) { return(0); } x = NetworkHelper.ReadInt16(br); z = NetworkHelper.ReadInt16(br); y = NetworkHelper.ReadInt16(br); } byte type = br.ReadByte(); try { Map.SetTileAndUpdate(new Vector3(x, y, z), type); } catch { Console.WriteLine("Cannot update tile!"); } } break; case MinecraftServerPacketId.SpawnPlayer: { if (ENABLE_FORTRESS) { totalread += 1 + NetworkHelper.StringLength + 4 + 4 + 4 + 1 + 1; if (received.Count < totalread) { return(0); } } else { totalread += 1 + NetworkHelper.StringLength + 2 + 2 + 2 + 1 + 1; if (received.Count < totalread) { return(0); } } byte playerid = br.ReadByte(); string playername = NetworkHelper.ReadString64(br); if (ENABLE_FORTRESS && playerid == 255) { spawned = true; break; } connectedplayers.Add(new ConnectedPlayer() { name = playername, id = playerid }); if (Clients.Players.ContainsKey(playerid)) { //throw new Exception(); } Clients.Players[playerid] = new Player(); Clients.Players[playerid].Name = playername; if (ENABLE_FORTRESS && ((DateTime.Now - loadedtime).TotalSeconds > 10)) { ReadAndUpdatePlayerPosition(br, playerid); } if (!ENABLE_FORTRESS) { ReadAndUpdatePlayerPosition(br, playerid); } if (playerid == 255) { spawned = true; } } break; case MinecraftServerPacketId.PlayerTeleport: { if (ENABLE_FORTRESS) { totalread += 1 + (4 + 4 + 4) + 1 + 1; if (received.Count < totalread) { return(0); } } else { totalread += 1 + (2 + 2 + 2) + 1 + 1; if (received.Count < totalread) { return(0); } } byte playerid = br.ReadByte(); ReadAndUpdatePlayerPosition(br, playerid); } break; case MinecraftServerPacketId.PositionandOrientationUpdate: { totalread += 1 + (1 + 1 + 1) + 1 + 1; if (received.Count < totalread) { return(0); } byte playerid = br.ReadByte(); float x = (float)br.ReadSByte() / 32; float y = (float)br.ReadSByte() / 32; float z = (float)br.ReadSByte() / 32; byte heading = br.ReadByte(); byte pitch = br.ReadByte(); Vector3 v = new Vector3(x, y, z); UpdatePositionDiff(playerid, v); } break; case MinecraftServerPacketId.PositionUpdate: { totalread += 1 + 1 + 1 + 1; if (received.Count < totalread) { return(0); } byte playerid = br.ReadByte(); float x = (float)br.ReadSByte() / 32; float y = (float)br.ReadSByte() / 32; float z = (float)br.ReadSByte() / 32; Vector3 v = new Vector3(x, y, z); UpdatePositionDiff(playerid, v); } break; case MinecraftServerPacketId.OrientationUpdate: { totalread += 1 + 1 + 1; if (received.Count < totalread) { return(0); } byte playerid = br.ReadByte(); byte heading = br.ReadByte(); byte pitch = br.ReadByte(); Clients.Players[playerid].Heading = heading; Clients.Players[playerid].Pitch = pitch; } break; case MinecraftServerPacketId.DespawnPlayer: { totalread += 1; if (received.Count < totalread) { return(0); } byte playerid = br.ReadByte(); for (int i = 0; i < connectedplayers.Count; i++) { if (connectedplayers[i].id == playerid) { connectedplayers.RemoveAt(i); } } Clients.Players.Remove(playerid); } break; case MinecraftServerPacketId.Message: { totalread += 1 + NetworkHelper.StringLength; if (received.Count < totalread) { return(0); } byte unused = br.ReadByte(); string message = NetworkHelper.ReadString64(br); Chatlines.AddChatline(message); ChatLog(message); } break; case MinecraftServerPacketId.DisconnectPlayer: { totalread += NetworkHelper.StringLength; if (received.Count < totalread) { return(0); } string disconnectReason = NetworkHelper.ReadString64(br); throw new Exception(disconnectReason); } case MinecraftServerPacketId.ExtendedPacketCommand: { totalread += 1 + 4 + 4; if (received.Count < totalread) { return(0); } int playerid = br.ReadByte(); int cmdframe = NetworkHelper.ReadInt32(br); int length = NetworkHelper.ReadInt32(br); totalread += length; if (received.Count < totalread) { return(0); } byte[] cmd = br.ReadBytes(length); gameworld.EnqueueCommand(playerid, cmdframe, cmd); } break; case MinecraftServerPacketId.ExtendedPacketTick: { totalread += 4 + 4; if (received.Count < totalread) { return(0); } int allowedframe = NetworkHelper.ReadInt32(br); int hash = NetworkHelper.ReadInt32(br); totalread += 1; if (received.Count < totalread) { return(0); } int clientscount = br.ReadByte(); totalread += clientscount * (1 + (3 * 4) + 1 + 1); if (received.Count < totalread) { return(0); } Dictionary <int, PlayerPosition> playerpositions = new Dictionary <int, PlayerPosition>(); for (int i = 0; i < clientscount; i++) { byte playerid = br.ReadByte(); //copied float x = (float)((double)NetworkHelper.ReadInt32(br) / 32); float y = (float)((double)NetworkHelper.ReadInt32(br) / 32); float z = (float)((double)NetworkHelper.ReadInt32(br) / 32); byte heading = br.ReadByte(); byte pitch = br.ReadByte(); playerpositions[playerid] = new PlayerPosition() { position = new Vector3(x, y, z), heading = heading, pitch = pitch }; } gameworld.KeyFrame(allowedframe, hash, playerpositions); } break; default: { throw new Exception("Invalid packet id"); } } return(totalread); }