From af6f655d5e8e9babf3d00175d611f8f9d6cead1b Mon Sep 17 00:00:00 2001 From: Milutinke Date: Thu, 18 Aug 2022 20:58:49 +0200 Subject: [PATCH] Fixed the requested changes for Terrain Movement. Tested and working. --- MinecraftClient/Commands/Move.cs | 12 +++-- MinecraftClient/Mapping/Dimension.cs | 45 +++++++++++-------- MinecraftClient/Mapping/Location.cs | 12 +---- MinecraftClient/Mapping/Movement.cs | 15 +++---- MinecraftClient/Mapping/World.cs | 25 +++++------ .../Protocol/Handlers/Protocol18.cs | 17 ++++--- .../Protocol/Handlers/Protocol18Terrain.cs | 6 +-- 7 files changed, 60 insertions(+), 72 deletions(-) diff --git a/MinecraftClient/Commands/Move.cs b/MinecraftClient/Commands/Move.cs index 8b5fecab..6e9e7e2b 100644 --- a/MinecraftClient/Commands/Move.cs +++ b/MinecraftClient/Commands/Move.cs @@ -18,7 +18,7 @@ namespace MinecraftClient.Commands if (args.Count < 1) { - string desc = GetCmdDescTranslated(); + string desc = GetCmdDescTranslated(); if (handler.GetTerrainEnabled()) handler.Log.Info(getChunkLoadingStatus(handler.GetWorld())); @@ -64,12 +64,10 @@ namespace MinecraftClient.Commands case "north": direction = Direction.North; break; case "south": direction = Direction.South; break; case "center": - { - Location current = handler.GetCurrentLocation(); - Location currentCenter = new Location(Math.Floor(current.X) + 0.5, current.Y, Math.Floor(current.Z) + 0.5); - handler.MoveTo(currentCenter, allowDirectTeleport: true); - return Translations.Get("cmd.move.walk", currentCenter, current); - } + Location current = handler.GetCurrentLocation(); + Location currentCenter = new Location(Math.Floor(current.X) + 0.5, current.Y, Math.Floor(current.Z) + 0.5); + handler.MoveTo(currentCenter, allowDirectTeleport: true); + return Translations.Get("cmd.move.walk", currentCenter, current); case "get": return handler.GetCurrentLocation().ToString(); default: return Translations.Get("cmd.look.unknown", args[0]); } diff --git a/MinecraftClient/Mapping/Dimension.cs b/MinecraftClient/Mapping/Dimension.cs index 987209ff..75642d51 100644 --- a/MinecraftClient/Mapping/Dimension.cs +++ b/MinecraftClient/Mapping/Dimension.cs @@ -20,17 +20,17 @@ namespace MinecraftClient.Mapping /// /// Whether piglins shake and transform to zombified piglins. /// - public readonly bool piglinSafe; + public readonly bool piglinSafe = false; /// - /// When false, compasses spin randomly. When true, nether portals can spawn zombified piglins. + /// When false, compasses spin randomly. When true, nether portals can spawn zombified piglins. /// - public readonly bool natural; + public readonly bool natural = true; /// /// How much light the dimension has. /// - public readonly float ambientLight; + public readonly float ambientLight = 0.0f; /// @@ -42,35 +42,36 @@ namespace MinecraftClient.Mapping /// /// A resource location defining what block tag to use for infiniburn. - /// Value: "" or minecraft resource "minecraft:...". + /// Value above 1.18.2: "#" or minecraft resource "#minecraft:...". + /// Value below 1.18.1: "" or minecraft resource "minecraft:...". /// - public readonly string infiniburn; + public readonly string infiniburn = "#minecraft:infiniburn_overworld"; /// /// Whether players can charge and use respawn anchors. /// - public readonly bool respawnAnchorWorks; + public readonly bool respawnAnchorWorks = false; /// /// Whether the dimension has skylight access or not. /// - public readonly bool hasSkylight; + public readonly bool hasSkylight = true; /// /// Whether players can use a bed to sleep. /// - public readonly bool bedWorks; + public readonly bool bedWorks = true; /// /// unknown /// Values: "minecraft:overworld", "minecraft:the_nether", "minecraft:the_end" or something else. /// - public readonly string effects; + public readonly string effects = "minecraft:overworld"; /// /// Whether players with the Bad Omen effect can cause a raid. /// - public readonly bool hasRaids; + public readonly bool hasRaids = true; /// /// The minimum Y level. @@ -78,7 +79,7 @@ namespace MinecraftClient.Mapping public readonly int minY = 0; /// - /// The minimum Y level. + /// The maximum Y level. /// public readonly int maxY = 256; @@ -90,30 +91,36 @@ namespace MinecraftClient.Mapping /// /// The maximum height to which chorus fruits and nether portals can bring players within this dimension. /// - public readonly int logicalHeight; + public readonly int logicalHeight = 256; /// /// The multiplier applied to coordinates when traveling to the dimension. /// - public readonly double coordinateScale; + public readonly double coordinateScale = 1.0; /// /// Whether the dimensions behaves like the nether (water evaporates and sponges dry) or not. Also causes lava to spread thinner. /// - public readonly bool ultrawarm; + public readonly bool ultrawarm = false; /// /// Whether the dimension has a bedrock ceiling or not. When true, causes lava to spread faster. /// - public readonly bool hasCeiling; + public readonly bool hasCeiling = false; + /// + /// Default value used in version below 1.17 + /// + public Dimension() + { + this.Name = "minecraft:overworld"; + } /// /// Create from the "Dimension Codec" NBT Tag Compound /// - /// ChunkColumn X - /// ChunkColumn Y - /// chunk at the given location + /// Dimension name + /// The dimension type (NBT Tag Compound) public Dimension(string name, Dictionary nbt) { if (name == null) diff --git a/MinecraftClient/Mapping/Location.cs b/MinecraftClient/Mapping/Location.cs index 9dab848a..cf45c493 100644 --- a/MinecraftClient/Mapping/Location.cs +++ b/MinecraftClient/Mapping/Location.cs @@ -14,7 +14,7 @@ namespace MinecraftClient.Mapping /// The X Coordinate /// public double X; - + /// /// The Y Coordinate (vertical) /// @@ -25,11 +25,6 @@ namespace MinecraftClient.Mapping /// public double Z; - /// - /// Current world: to get the lowest Y coordinate - /// - public static World world; - /// /// Get location with zeroed coordinates /// @@ -84,10 +79,7 @@ namespace MinecraftClient.Mapping { get { - if (world.GetDimension() == null) - return (int)Math.Floor(Y / Chunk.SizeY); // below 1.16.2, Y coordinate always start from zero - else - return (int)Math.Floor((Y - world.GetDimension().minY) / Chunk.SizeY); + return (int)Math.Floor((Y - World.GetDimension().minY) / Chunk.SizeY); } } diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs index 960921b7..41bed746 100644 --- a/MinecraftClient/Mapping/Movement.cs +++ b/MinecraftClient/Mapping/Movement.cs @@ -33,8 +33,7 @@ namespace MinecraftClient.Mapping } if (!IsOnGround(world, location) && !IsSwimming(world, location)) { - while (!IsOnGround(world, belowFoots) && - belowFoots.Y >= 1 + (world.GetDimension() == null ? 0 : world.GetDimension().minY)) + while (!IsOnGround(world, belowFoots) && belowFoots.Y >= 1 + World.GetDimension().minY) belowFoots = Move(belowFoots, Direction.Down); location = Move2Steps(location, belowFoots, ref motionY, true).Dequeue(); } @@ -62,7 +61,7 @@ namespace MinecraftClient.Mapping } else { - foreach (Direction dir in new []{ Direction.East, Direction.West, Direction.North, Direction.South }) + foreach (Direction dir in new[] { Direction.East, Direction.West, Direction.North, Direction.South }) if (CanMove(world, location, dir) && IsOnGround(world, Move(location, dir)) && (allowUnsafe || IsSafe(world, Move(location, dir)))) availableMoves.Add(Move(location, dir)); availableMoves.Add(Move(location, Direction.Down)); @@ -168,7 +167,7 @@ namespace MinecraftClient.Mapping if (minOffset > maxOffset) throw new ArgumentException("minOffset must be lower or equal to maxOffset", "minOffset"); - + // We always use distance squared so our limits must also be squared. minOffset *= minOffset; maxOffset *= maxOffset; @@ -193,8 +192,8 @@ namespace MinecraftClient.Mapping : new KeyValuePair(location, int.MaxValue)) .OrderBy(pair => pair.Value). // Sort for h-score (f-score - g-score) to get smallest distance to goal if f-scores are equal - ThenBy(pair => f_score[pair.Key]-g_score[pair.Key]).First().Key; - + ThenBy(pair => f_score[pair.Key] - g_score[pair.Key]).First().Key; + // Only assert a value if it is of actual use later if (maxOffset > 0 && ClosedSet.Count > 0) // Get the block that currently is closest to the goal @@ -229,7 +228,7 @@ namespace MinecraftClient.Mapping } // Goal could not be reached. Set the path to the closest location if close enough - if (maxOffset == int.MaxValue || goal.DistanceSquared(closestGoal) <= maxOffset) + if (maxOffset == int.MaxValue || goal.DistanceSquared(closestGoal) <= maxOffset) return ReconstructPath(Came_From, closestGoal); else return null; @@ -290,7 +289,7 @@ namespace MinecraftClient.Mapping public static bool IsSafe(World world, Location location) { return - //No block that can harm the player + //No block that can harm the player !world.GetBlock(location).Type.CanHarmPlayers() && !world.GetBlock(Move(location, Direction.Up)).Type.CanHarmPlayers() && !world.GetBlock(Move(location, Direction.Down)).Type.CanHarmPlayers() diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 39b5f0c4..aee80a25 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -19,7 +19,7 @@ namespace MinecraftClient.Mapping /// /// The dimension info of the world /// - private Dimension dimension; + private static Dimension dimension = new Dimension(); /// /// Lock for thread safety @@ -29,8 +29,8 @@ namespace MinecraftClient.Mapping /// /// Chunk data parsing progress /// - public uint chunkCnt = 0; - public uint chunkLoadNotCompleted = 0; + public int chunkCnt = 0; + public int chunkLoadNotCompleted = 0; /// /// Read, set or unload the specified chunk column @@ -89,28 +89,24 @@ namespace MinecraftClient.Mapping } } - public World() - { - Location.world = this; - } - /// /// Set dimension type /// /// The name of the dimension type /// The dimension type (NBT Tag Compound) - public void SetDimension(string name, Dictionary nbt) + public static void SetDimension(string name, Dictionary nbt) { - this.dimension = new Dimension(name, nbt); + // will change in 1.19 and above + dimension = new Dimension(name, nbt); } /// - /// Get dimension type + /// Get current dimension /// - /// The chunk column - public Dimension GetDimension() + /// Current dimension + public static Dimension GetDimension() { - return this.dimension; + return dimension; } /// @@ -211,7 +207,6 @@ namespace MinecraftClient.Mapping try { chunks = new Dictionary>(); - dimension = null; } finally { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 1ff2d13b..a5f35dbb 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -332,7 +332,7 @@ namespace MinecraftClient.Protocol.Handlers currentDimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above if (protocolversion >= MC1162Version) - handler.GetWorld().SetDimension(currentDimensionName, currentDimensionType); + World.SetDimension(currentDimensionName, currentDimensionType); if (protocolversion >= MC115Version) dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above @@ -391,10 +391,7 @@ namespace MinecraftClient.Protocol.Handlers dimensionNameInRespawn = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above if (protocolversion >= MC1162Version) - new Task(() => - { - handler.GetWorld().SetDimension(dimensionNameInRespawn, dimensionTypeInRespawn); - }).Start(); + World.SetDimension(dimensionNameInRespawn, dimensionTypeInRespawn); if (protocolversion < MC114Version) dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below @@ -470,12 +467,13 @@ namespace MinecraftClient.Protocol.Handlers } int dataSize = dataTypes.ReadNextVarInt(packetData); // Size + + Interlocked.Increment(ref handler.GetWorld().chunkCnt); + Interlocked.Increment(ref handler.GetWorld().chunkLoadNotCompleted); new Task(() => { - handler.GetWorld().chunkCnt++; - handler.GetWorld().chunkLoadNotCompleted++; pTerrain.ProcessChunkColumnData(chunkX, chunkZ, verticalStripBitmask, packetData); - handler.GetWorld().chunkLoadNotCompleted--; + Interlocked.Decrement(ref handler.GetWorld().chunkLoadNotCompleted); }).Start(); } else @@ -752,7 +750,8 @@ namespace MinecraftClient.Protocol.Handlers int chunkZ = dataTypes.ReadNextInt(packetData); if (handler.GetWorld()[chunkX, chunkZ] != null) - handler.GetWorld().chunkCnt--; + Interlocked.Decrement(ref handler.GetWorld().chunkCnt); + // Warning: It is legal to include unloaded chunks in the UnloadChunk packet. Since chunks that have not been loaded are not recorded, this may result in loading chunks that should be unloaded and inaccurate statistics. handler.GetWorld()[chunkX, chunkZ] = null; } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs index 73593da6..a66655a4 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs @@ -147,10 +147,8 @@ namespace MinecraftClient.Protocol.Handlers public void ProcessChunkColumnData(int chunkX, int chunkZ, ulong[] verticalStripBitmask, Queue cache) { var world = handler.GetWorld(); - if (world.GetDimension() == null) - return; - int chunkColumnSize = (world.GetDimension().height + 15) / 16; + int chunkColumnSize = (World.GetDimension().height + 15) / 16; // Round up if (protocolversion >= Protocol18Handler.MC117Version) { @@ -223,7 +221,7 @@ namespace MinecraftClient.Protocol.Handlers /// Cache for reading chunk data public void ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, ushort chunkMask2, bool hasSkyLight, bool chunksContinuous, int currentDimension, Queue cache) { - const int chunkColumnSize = 16; + const int chunkColumnSize = 16; if (protocolversion >= Protocol18Handler.MC19Version) { // 1.9 and above chunk format