From 6430f13d3eb2288ce08800e39f8ac89c7f5b12fb Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 14:54:49 +0800 Subject: [PATCH 01/12] Add "/chunk status" command --- MinecraftClient/Commands/Chunk.cs | 157 ++++++++++++++++++++++++++ MinecraftClient/Resources/lang/en.ini | 3 + 2 files changed, 160 insertions(+) create mode 100644 MinecraftClient/Commands/Chunk.cs diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs new file mode 100644 index 00000000..2765a4cd --- /dev/null +++ b/MinecraftClient/Commands/Chunk.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Commands +{ + public class Chunk : Command + { + public override string CmdName { get { return "chunk"; } } + public override string CmdUsage { get { return "chunk status"; } } + public override string CmdDesc { get { return "cmd.chunk.desc"; } } + + public override string Run(McClient handler, string command, Dictionary? localVars) + { + if (hasArg(command)) + { + string[] args = getArgs(command); + if (args.Length > 0) + { + if (args[0] == "status") + { + World world = handler.GetWorld(); + Location current = handler.GetCurrentLocation(); + StringBuilder sb = new(); + sb.Append("Current position:"); + sb.Append(current.ToString()); + sb.Append(", chunk: "); + sb.Append(String.Format("({0}, {1})", current.ChunkX, current.ChunkZ)); + sb.Append(".\n"); + + sb.Append(getChunkLoadingStatus(handler.GetWorld())); + sb.Append('\n'); + + int startX = current.ChunkX - 16; + int startZ = current.ChunkZ - 16; + for (int dz = 0; dz < 32; dz++) + { + for (int dx = 0; dx < 32; ++dx) + { + ChunkColumn? chunkColumn = world[startX + dx, startZ + dz]; + if (dz == 16 && dx == 16) + sb.Append("§w"); // Player Location: background red + + if (chunkColumn == null) + sb.Append("🔳"); // empty + else if (chunkColumn.FullyLoaded) + sb.Append("🟩"); // green + else + sb.Append("🟨"); // yellow + + if (dz == 16 && dx == 16) + sb.Append("§r"); + } + sb.Append('\n'); + } + + sb.Append("PlayerLocation:§w §r, NotReceived:🔳, Loading:🟨, Loaded:🟩."); + return sb.ToString(); + } + else if (args[0] == "setloading") // Debug only! + { + Tuple? chunkPos = ParseChunkPos(args); + if (chunkPos != null) + { + World world = handler.GetWorld(); + (int chunkX, int chunkZ) = chunkPos; + ChunkColumn? chunkColumn = world[chunkX, chunkZ]; + if (chunkColumn != null) + chunkColumn.FullyLoaded = false; + return (chunkColumn == null) ? "Fail: chunk dosen't exist!" : + String.Format("Successfully marked chunk ({0}, {1}) as loading.", chunkX, chunkZ); + } + else + return GetCmdDescTranslated(); + } + else if (args[0] == "setloaded") // Debug only! + { + Tuple? chunkPos = ParseChunkPos(args); + if (chunkPos != null) + { + World world = handler.GetWorld(); + (int chunkX, int chunkZ) = chunkPos; + ChunkColumn? chunkColumn = world[chunkX, chunkZ]; + if (chunkColumn != null) + chunkColumn.FullyLoaded = true; + return (chunkColumn == null) ? "Fail: chunk dosen't exist!" : + String.Format("Successfully marked chunk ({0}, {1}) as loaded.", chunkX, chunkZ); + } + else + return GetCmdDescTranslated(); + } + else if (args[0] == "delete") // Debug only! + { + Tuple? chunkPos = ParseChunkPos(args); + if (chunkPos != null) + { + World world = handler.GetWorld(); + (int chunkX, int chunkZ) = chunkPos; + world[chunkX, chunkZ] = null; + return String.Format("Successfully deleted chunk ({0}, {1}).", chunkX, chunkZ); + } + else + return GetCmdDescTranslated(); + } + else + return GetCmdDescTranslated(); + } + else + return GetCmdDescTranslated(); + } + else + return GetCmdDescTranslated(); + } + + private Tuple? ParseChunkPos(string[] args) + { + try + { + int chunkX, chunkZ; + if (args.Length == 1 + 3) + { + Location pos = new(int.Parse(args[1]), int.Parse(args[2]), int.Parse(args[3])); + chunkX = pos.ChunkX; + chunkZ = pos.ChunkZ; + } + else if (args.Length == 1 + 2) + { + chunkX = int.Parse(args[1]); + chunkZ = int.Parse(args[2]); + } + else + return null; + return new(chunkX, chunkZ); + } + catch (FormatException) + { + return null; + } + } + + private string getChunkLoadingStatus(World world) + { + double chunkLoadedRatio; + if (world.chunkCnt == 0) + chunkLoadedRatio = 0; + else + chunkLoadedRatio = (world.chunkCnt - world.chunkLoadNotCompleted) / (double)world.chunkCnt; + + string status = Translations.Get("cmd.move.chunk_loading_status", + chunkLoadedRatio, world.chunkCnt - world.chunkLoadNotCompleted, world.chunkCnt); + + return status; + } + } +} diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index 49bbfd8f..be936f2c 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -227,6 +227,9 @@ cmd.changeSlot.nan=Could not change slot: Not a Number cmd.changeSlot.changed=Changed to slot {0} cmd.changeSlot.fail=Could not change slot +# Chunk +cmd.chunk.desc=Displays the chunk loading status. + # Connect cmd.connect.desc=connect to the specified server. cmd.connect.unknown=Unknown account '{0}'. From c50477a712adad8bcf21e2255c775389b2cb783c Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 15:25:27 +0800 Subject: [PATCH 02/12] Marking chunk --- MinecraftClient/Commands/Chunk.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index 2765a4cd..0990b801 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -9,7 +9,7 @@ namespace MinecraftClient.Commands public class Chunk : Command { public override string CmdName { get { return "chunk"; } } - public override string CmdUsage { get { return "chunk status"; } } + public override string CmdUsage { get { return "chunk status [chunkX chunkZ|locationX locationY locationZ]"; } } public override string CmdDesc { get { return "cmd.chunk.desc"; } } public override string Run(McClient handler, string command, Dictionary? localVars) @@ -23,6 +23,10 @@ namespace MinecraftClient.Commands { World world = handler.GetWorld(); Location current = handler.GetCurrentLocation(); + + Tuple? markedChunkPos = ParseChunkPos(args); + (int markChunkX, int markChunkZ) = (markedChunkPos == null) ? new(current.ChunkX, current.ChunkZ) : markedChunkPos; + StringBuilder sb = new(); sb.Append("Current position:"); sb.Append(current.ToString()); @@ -40,7 +44,7 @@ namespace MinecraftClient.Commands for (int dx = 0; dx < 32; ++dx) { ChunkColumn? chunkColumn = world[startX + dx, startZ + dz]; - if (dz == 16 && dx == 16) + if ((dz == 16 && dx == 16) || (startZ + dz == markChunkZ && startX + dx == markChunkX)) sb.Append("§w"); // Player Location: background red if (chunkColumn == null) @@ -50,13 +54,13 @@ namespace MinecraftClient.Commands else sb.Append("🟨"); // yellow - if (dz == 16 && dx == 16) + if ((dz == 16 && dx == 16) || (startZ + dz == markChunkZ && startX + dx == markChunkX)) sb.Append("§r"); } sb.Append('\n'); } - sb.Append("PlayerLocation:§w §r, NotReceived:🔳, Loading:🟨, Loaded:🟩."); + sb.Append("Player or marked chunk:§w §r, NotReceived:🔳, Loading:🟨, Loaded:🟩"); return sb.ToString(); } else if (args[0] == "setloading") // Debug only! @@ -121,7 +125,7 @@ namespace MinecraftClient.Commands int chunkX, chunkZ; if (args.Length == 1 + 3) { - Location pos = new(int.Parse(args[1]), int.Parse(args[2]), int.Parse(args[3])); + Location pos = new(double.Parse(args[1]), double.Parse(args[2]), double.Parse(args[3])); chunkX = pos.ChunkX; chunkZ = pos.ChunkZ; } From 3dac1f41d19a2c02f0160e3aecc0a74afad5b490 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 16:10:34 +0800 Subject: [PATCH 03/12] Add tips --- MinecraftClient/Commands/Chunk.cs | 28 ++++++++++++++++++--------- MinecraftClient/Commands/Move.cs | 4 ++-- MinecraftClient/Resources/lang/en.ini | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index 0990b801..88bf7776 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -25,18 +25,26 @@ namespace MinecraftClient.Commands Location current = handler.GetCurrentLocation(); Tuple? markedChunkPos = ParseChunkPos(args); - (int markChunkX, int markChunkZ) = (markedChunkPos == null) ? new(current.ChunkX, current.ChunkZ) : markedChunkPos; + (int markChunkX, int markChunkZ) = markedChunkPos ?? (new(current.ChunkX, current.ChunkZ)); StringBuilder sb = new(); - sb.Append("Current position:"); - sb.Append(current.ToString()); - sb.Append(", chunk: "); - sb.Append(String.Format("({0}, {1})", current.ChunkX, current.ChunkZ)); - sb.Append(".\n"); sb.Append(getChunkLoadingStatus(handler.GetWorld())); sb.Append('\n'); + sb.Append(String.Format("Current location:{0}, chunk: ({1}, {2}).\n", current, current.ChunkX, current.ChunkZ)); + if (markedChunkPos != null) + { + sb.Append("Marked location: "); + if (args.Length == 1 + 3) + sb.Append(String.Format("X:{0:0.00} Y:{1:0.00} Z:{2:0.00}, ", double.Parse(args[1]), double.Parse(args[2]), double.Parse(args[3]))); + sb.Append(String.Format("chunk: ({0}, {1}).\n", markChunkX, markChunkZ)); + } + + if (markedChunkPos != null && + (markChunkX < current.ChunkX - 16 || markChunkX > current.ChunkX + 16 || markChunkZ < current.ChunkZ - 16 || markChunkZ > current.ChunkZ + 16)) + sb.Append("§x§0Since the marked block is outside the graph, it will not be displayed!§r\n"); + int startX = current.ChunkX - 16; int startZ = current.ChunkZ - 16; for (int dz = 0; dz < 32; dz++) @@ -44,8 +52,10 @@ namespace MinecraftClient.Commands for (int dx = 0; dx < 32; ++dx) { ChunkColumn? chunkColumn = world[startX + dx, startZ + dz]; - if ((dz == 16 && dx == 16) || (startZ + dz == markChunkZ && startX + dx == markChunkX)) - sb.Append("§w"); // Player Location: background red + if (dz == 16 && dx == 16) + sb.Append("§z"); // Player Location: background gray + else if (startZ + dz == markChunkZ && startX + dx == markChunkX) + sb.Append("§w"); // Marked chunk: background red if (chunkColumn == null) sb.Append("🔳"); // empty @@ -60,7 +70,7 @@ namespace MinecraftClient.Commands sb.Append('\n'); } - sb.Append("Player or marked chunk:§w §r, NotReceived:🔳, Loading:🟨, Loaded:🟩"); + sb.Append("Player:§z §r, MarkedChunk:§w §r, NotReceived:🔳, Loading:🟨, Loaded:🟩"); return sb.ToString(); } else if (args[0] == "setloading") // Debug only! diff --git a/MinecraftClient/Commands/Move.cs b/MinecraftClient/Commands/Move.cs index 7fa718b0..8922b88e 100644 --- a/MinecraftClient/Commands/Move.cs +++ b/MinecraftClient/Commands/Move.cs @@ -76,7 +76,7 @@ namespace MinecraftClient.Commands ChunkColumn? chunkColumn = handler.GetWorld().GetChunkColumn(goal); if (chunkColumn == null || chunkColumn.FullyLoaded == false) - return Translations.Get("cmd.move.chunk_not_loaded"); + return Translations.Get("cmd.move.chunk_not_loaded", goal.X, goal.Y, goal.Z); if (Movement.CanMove(handler.GetWorld(), handler.GetCurrentLocation(), direction)) { @@ -99,7 +99,7 @@ namespace MinecraftClient.Commands ChunkColumn? chunkColumn = handler.GetWorld().GetChunkColumn(goal); if (chunkColumn == null || chunkColumn.FullyLoaded == false) - return Translations.Get("cmd.move.chunk_not_loaded"); + return Translations.Get("cmd.move.chunk_not_loaded", x, y, z); if (takeRisk || Movement.PlayerFitsHere(handler.GetWorld(), goal)) { diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index be936f2c..ba86f955 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -337,7 +337,7 @@ cmd.move.suggestforce=Failed to compute a safe path to {0}. Try -f parameter to cmd.move.gravity.enabled=Gravity is enabled. cmd.move.gravity.disabled=Gravity is disabled. cmd.move.chunk_loading_status=Chunk loading status: {0:P} - {1} out of {2} load completed. -cmd.move.chunk_not_loaded=The chunk where the target location resides has not yet been loaded. +cmd.move.chunk_not_loaded=The chunk where the target location resides has not yet been loaded.\nYou can use "/chunk status {0:0.0} {1:0.0} {2:0.0}" to check the chunk loading status. # Reco cmd.reco.desc=restart and reconnect to the server. From e69305f4fc74c7cc11fb79eeb7c8b338f0f7e49f Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 21:40:44 +0800 Subject: [PATCH 04/12] Trim --- MinecraftClient/Commands/Chunk.cs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index 88bf7776..acaafcc3 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -42,8 +42,8 @@ namespace MinecraftClient.Commands } if (markedChunkPos != null && - (markChunkX < current.ChunkX - 16 || markChunkX > current.ChunkX + 16 || markChunkZ < current.ChunkZ - 16 || markChunkZ > current.ChunkZ + 16)) - sb.Append("§x§0Since the marked block is outside the graph, it will not be displayed!§r\n"); + (markChunkX < current.ChunkX - 16 || markChunkX >= current.ChunkX + 16 || markChunkZ < current.ChunkZ - 16 || markChunkZ >= current.ChunkZ + 16)) + sb.Append("§x§0Since the marked chunk is outside the graph, it will not be displayed!§r\n"); int startX = current.ChunkX - 16; int startZ = current.ChunkZ - 16; @@ -58,11 +58,11 @@ namespace MinecraftClient.Commands sb.Append("§w"); // Marked chunk: background red if (chunkColumn == null) - sb.Append("🔳"); // empty + sb.Append("\ud83d\udd33"); // "🔳" white hollow square else if (chunkColumn.FullyLoaded) - sb.Append("🟩"); // green + sb.Append("\ud83d\udfe9"); // "🟩" green else - sb.Append("🟨"); // yellow + sb.Append("\ud83d\udfe8"); // "🟨" yellow if ((dz == 16 && dx == 16) || (startZ + dz == markChunkZ && startX + dx == markChunkX)) sb.Append("§r"); @@ -70,14 +70,15 @@ namespace MinecraftClient.Commands sb.Append('\n'); } - sb.Append("Player:§z §r, MarkedChunk:§w §r, NotReceived:🔳, Loading:🟨, Loaded:🟩"); + sb.Append("Player:§z §r, MarkedChunk:§w §r, NotReceived:\ud83d\udd33, Loading:\ud83d\udfe8, Loaded:\ud83d\udfe9"); return sb.ToString(); } - else if (args[0] == "setloading") // Debug only! + else if (args[0] == "setloading") // For debugging { Tuple? chunkPos = ParseChunkPos(args); if (chunkPos != null) { + handler.Log.Info("§x§0This command is used for debugging, make sure you know what you are doing.§r"); World world = handler.GetWorld(); (int chunkX, int chunkZ) = chunkPos; ChunkColumn? chunkColumn = world[chunkX, chunkZ]; @@ -89,11 +90,12 @@ namespace MinecraftClient.Commands else return GetCmdDescTranslated(); } - else if (args[0] == "setloaded") // Debug only! + else if (args[0] == "setloaded") // For debugging { Tuple? chunkPos = ParseChunkPos(args); if (chunkPos != null) { + handler.Log.Info("§x§0This command is used for debugging, make sure you know what you are doing.§r"); World world = handler.GetWorld(); (int chunkX, int chunkZ) = chunkPos; ChunkColumn? chunkColumn = world[chunkX, chunkZ]; @@ -105,11 +107,12 @@ namespace MinecraftClient.Commands else return GetCmdDescTranslated(); } - else if (args[0] == "delete") // Debug only! + else if (args[0] == "delete") // For debugging { Tuple? chunkPos = ParseChunkPos(args); if (chunkPos != null) { + handler.Log.Info("§x§0This command is used for debugging, make sure you know what you are doing.§r"); World world = handler.GetWorld(); (int chunkX, int chunkZ) = chunkPos; world[chunkX, chunkZ] = null; From ecb5d1e2ce5e42920c17099042de435815008c30 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 22:43:56 +0800 Subject: [PATCH 05/12] Fix #2159 --- MinecraftClient/Mapping/Dimension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinecraftClient/Mapping/Dimension.cs b/MinecraftClient/Mapping/Dimension.cs index 72cdf844..d260ce71 100644 --- a/MinecraftClient/Mapping/Dimension.cs +++ b/MinecraftClient/Mapping/Dimension.cs @@ -182,7 +182,7 @@ namespace MinecraftClient.Mapping this.height = (int)nbt["height"]; if (nbt.ContainsKey("min_y") && nbt.ContainsKey("height")) this.maxY = this.minY + this.height; - if (nbt.ContainsKey("logical_height")) + if (nbt.ContainsKey("logical_height") && nbt["logical_height"].GetType() != typeof(byte)) this.logicalHeight = (int)nbt["logical_height"]; if (nbt.ContainsKey("coordinate_scale")) { From 5cb97ee00b3a4ef75ae1ff8a7cf2735f2e4a1461 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 23:21:14 +0800 Subject: [PATCH 06/12] Adaptable width --- MinecraftClient/Commands/Chunk.cs | 61 +++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index acaafcc3..03d3c006 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -45,26 +45,57 @@ namespace MinecraftClient.Commands (markChunkX < current.ChunkX - 16 || markChunkX >= current.ChunkX + 16 || markChunkZ < current.ChunkZ - 16 || markChunkZ >= current.ChunkZ + 16)) sb.Append("§x§0Since the marked chunk is outside the graph, it will not be displayed!§r\n"); - int startX = current.ChunkX - 16; - int startZ = current.ChunkZ - 16; - for (int dz = 0; dz < 32; dz++) + + int consoleWid = Math.Max(Console.BufferWidth / 2, 21); + if (consoleWid % 2 == 0) + --consoleWid; + + int startZ = current.ChunkZ - consoleWid / 2, endZ = current.ChunkZ + 1 + consoleWid / 2; + int startX = current.ChunkX - consoleWid / 2, endX = current.ChunkX + 1 + consoleWid / 2; + int leftMost = endX, rightMost = startX, topMost = endZ, bottomMost = startZ; + + Dictionary, byte> chunkStatus = new(); + for (int z = startZ; z <= endZ; z++) { - for (int dx = 0; dx < 32; ++dx) + for (int x = startX; x <= endX; ++x) { - ChunkColumn? chunkColumn = world[startX + dx, startZ + dz]; - if (dz == 16 && dx == 16) - sb.Append("§z"); // Player Location: background gray - else if (startZ + dz == markChunkZ && startX + dx == markChunkX) - sb.Append("§w"); // Marked chunk: background red - + ChunkColumn? chunkColumn = world[x, z]; if (chunkColumn == null) - sb.Append("\ud83d\udd33"); // "🔳" white hollow square - else if (chunkColumn.FullyLoaded) - sb.Append("\ud83d\udfe9"); // "🟩" green + chunkStatus[new(x, z)] = 0; // "🔳" white hollow square else - sb.Append("\ud83d\udfe8"); // "🟨" yellow + { + leftMost = Math.Min(leftMost, x); + rightMost = Math.Max(rightMost, x); + topMost = Math.Min(topMost, z); + bottomMost = Math.Max(bottomMost, z); + if (chunkColumn.FullyLoaded) + chunkStatus[new(x, z)] = 1; // "🟩" green + else + chunkStatus[new(x, z)] = 2; // "🟨" yellow + } - if ((dz == 16 && dx == 16) || (startZ + dz == markChunkZ && startX + dx == markChunkX)) + } + } + + // Add a blank line + --topMost; + ++bottomMost; + if (Console.BufferWidth / 2 >= ((rightMost - leftMost + 1) + 2)) + { + --leftMost; + ++rightMost; + } + string[] chunkStatusToEmoji = new string[] { "\ud83d\udd33", "\ud83d\udfe9", "\ud83d\udfe8" }; + for (int z = topMost; z <= bottomMost; ++z) + { + for (int x = leftMost; x <= rightMost; ++x) + { + if (z == current.ChunkZ && x == current.ChunkX) + sb.Append("§z"); // Player Location: background gray + else if (z == markChunkZ && x == markChunkX) + sb.Append("§w"); // Marked chunk: background red + sb.Append(chunkStatusToEmoji[chunkStatus.GetValueOrDefault, byte>(new(x, z), 0)]); + if ((z == current.ChunkZ && x == current.ChunkX) || (z == markChunkZ && x == markChunkX)) sb.Append("§r"); } sb.Append('\n'); From 7e71fbf241a3d1b02a6f133c955c9dd397bc12b3 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 6 Sep 2022 23:39:45 +0800 Subject: [PATCH 07/12] Bug fix --- MinecraftClient/Commands/Chunk.cs | 34 ++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index 03d3c006..a686a23a 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -45,19 +45,23 @@ namespace MinecraftClient.Commands (markChunkX < current.ChunkX - 16 || markChunkX >= current.ChunkX + 16 || markChunkZ < current.ChunkZ - 16 || markChunkZ >= current.ChunkZ + 16)) sb.Append("§x§0Since the marked chunk is outside the graph, it will not be displayed!§r\n"); + int consoleHei = Math.Max(Console.BufferHeight - 2, 21); + if (consoleHei % 2 == 0) + --consoleHei; int consoleWid = Math.Max(Console.BufferWidth / 2, 21); if (consoleWid % 2 == 0) --consoleWid; - int startZ = current.ChunkZ - consoleWid / 2, endZ = current.ChunkZ + 1 + consoleWid / 2; + int startZ = current.ChunkZ - consoleHei / 2, endZ = current.ChunkZ + 1 + consoleHei / 2; int startX = current.ChunkX - consoleWid / 2, endX = current.ChunkX + 1 + consoleWid / 2; + int leftMost = endX, rightMost = startX, topMost = endZ, bottomMost = startZ; Dictionary, byte> chunkStatus = new(); - for (int z = startZ; z <= endZ; z++) + for (int z = startZ - 1; z <= endZ + 1; z++) { - for (int x = startX; x <= endX; ++x) + for (int x = startX - 1; x <= endX + 1; ++x) { ChunkColumn? chunkColumn = world[x, z]; if (chunkColumn == null) @@ -73,19 +77,29 @@ namespace MinecraftClient.Commands else chunkStatus[new(x, z)] = 2; // "🟨" yellow } - } } // Add a blank line - --topMost; - ++bottomMost; + if (topMost != startZ) + --topMost; + if (bottomMost != endZ) + ++bottomMost; if (Console.BufferWidth / 2 >= ((rightMost - leftMost + 1) + 2)) { - --leftMost; - ++rightMost; + if (leftMost != startX) + --leftMost; + if (rightMost != endX) + ++rightMost; } - string[] chunkStatusToEmoji = new string[] { "\ud83d\udd33", "\ud83d\udfe9", "\ud83d\udfe8" }; + else + { + leftMost = Math.Max(leftMost, startX); + rightMost = Math.Min(rightMost, endX); + } + + // Output + string[] chunkStatuToEmoji = new string[] { "\ud83d\udd33", "\ud83d\udfe9", "\ud83d\udfe8" }; for (int z = topMost; z <= bottomMost; ++z) { for (int x = leftMost; x <= rightMost; ++x) @@ -94,7 +108,7 @@ namespace MinecraftClient.Commands sb.Append("§z"); // Player Location: background gray else if (z == markChunkZ && x == markChunkX) sb.Append("§w"); // Marked chunk: background red - sb.Append(chunkStatusToEmoji[chunkStatus.GetValueOrDefault, byte>(new(x, z), 0)]); + sb.Append(chunkStatuToEmoji[chunkStatus.GetValueOrDefault, byte>(new(x, z), 0)]); if ((z == current.ChunkZ && x == current.ChunkX) || (z == markChunkZ && x == markChunkX)) sb.Append("§r"); } From 8ce5c40b287df73109e226efac12a3f00337c86c Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 7 Sep 2022 00:02:09 +0800 Subject: [PATCH 08/12] Another fix for #2159 --- MinecraftClient/Mapping/World.cs | 21 +++++++++++++---- .../Protocol/Handlers/Protocol18.cs | 23 +++++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 63ecb0c4..eea24e59 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -21,9 +21,9 @@ namespace MinecraftClient.Mapping /// /// The dimension info of the world /// - private static Dimension curDimension = new Dimension(); + private static Dimension curDimension = new(); - private static Dictionary? dimensionList = null; + private static Dictionary dimensionList = new(); /// /// Chunk data parsing progress @@ -61,16 +61,29 @@ namespace MinecraftClient.Mapping /// Registry Codec nbt data public static void StoreDimensionList(Dictionary registryCodec) { - dimensionList = new(); var dimensionListNbt = (object[])(((Dictionary)registryCodec["minecraft:dimension_type"])["value"]); foreach (Dictionary dimensionNbt in dimensionListNbt) { string dimensionName = (string)dimensionNbt["name"]; Dictionary element = (Dictionary)dimensionNbt["element"]; + if (dimensionList.ContainsKey(dimensionName)) + dimensionList.Remove(dimensionName); dimensionList.Add(dimensionName, new Dimension(dimensionName, element)); } } + /// + /// Store one dimension - 1.16.2 to 1.18.2 + /// + /// Dimension name + /// Dimension Type nbt data + public static void StoreDimension(string dimensionName, Dictionary dimensionType) + { + if (dimensionList.ContainsKey(dimensionName)) + dimensionList.Remove(dimensionName); + dimensionList.Add(dimensionName, new Dimension(dimensionName, dimensionType)); + } + /// /// Set current dimension - 1.16 and above @@ -79,7 +92,7 @@ namespace MinecraftClient.Mapping /// The dimension type (NBT Tag Compound) public static void SetDimension(string name) { - curDimension = dimensionList![name]; // Should not fail + curDimension = dimensionList[name]; // Should not fail } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index d05cf455..f60b62f4 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -371,7 +371,8 @@ namespace MinecraftClient.Protocol.Handlers for (int i = 0; i < worldCount; i++) dataTypes.ReadNextString(packetData); // Dimension Names (World Names) - 1.16 and above var registryCodec = dataTypes.ReadNextNbt(packetData); // Registry Codec (Dimension Codec) - 1.16 and above - World.StoreDimensionList(registryCodec); + if (handler.GetTerrainEnabled()) + World.StoreDimensionList(registryCodec); } // Current dimension @@ -380,12 +381,13 @@ namespace MinecraftClient.Protocol.Handlers // String identifier: 1.16 and 1.16.1 // varInt: [1.9.1 to 1.15.2] // byte: below 1.9.1 + Dictionary? dimensionType = null; if (protocolVersion >= MC_1_16_Version) { if (protocolVersion >= MC_1_19_Version) dataTypes.ReadNextString(packetData); // Dimension Type: Identifier else if (protocolVersion >= MC_1_16_2_Version) - dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound + dimensionType = dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound else dataTypes.ReadNextString(packetData); this.currentDimension = 0; @@ -401,7 +403,12 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_16_Version) { string dimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above - World.SetDimension(dimensionName); + if (handler.GetTerrainEnabled()) + { + if (protocolVersion >= MC_1_16_2_Version && protocolVersion < MC_1_19_Version) + World.StoreDimension(dimensionName, dimensionType!); + World.SetDimension(dimensionName); + } } if (protocolVersion >= MC_1_15_Version) @@ -594,12 +601,13 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.Respawn: + Dictionary? dimensionTypeRespawn = null; if (protocolVersion >= MC_1_16_Version) { if (protocolVersion >= MC_1_19_Version) dataTypes.ReadNextString(packetData); // Dimension Type: Identifier else if (protocolVersion >= MC_1_16_2_Version) - dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound + dimensionTypeRespawn = dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound else dataTypes.ReadNextString(packetData); this.currentDimension = 0; @@ -612,7 +620,12 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_16_Version) { string dimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above - World.SetDimension(dimensionName); + if (handler.GetTerrainEnabled()) + { + if (protocolVersion >= MC_1_16_2_Version && protocolVersion < MC_1_19_Version) + World.StoreDimension(dimensionName, dimensionTypeRespawn!); + World.SetDimension(dimensionName); + } } if (protocolVersion < MC_1_14_Version) From 4d4940a3b96b105e872a6be1416de8320884db3b Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 7 Sep 2022 00:08:31 +0800 Subject: [PATCH 09/12] Trim --- MinecraftClient/Mapping/World.cs | 10 ++++------ MinecraftClient/Protocol/Handlers/Protocol18.cs | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index eea24e59..47a768ad 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -65,19 +65,17 @@ namespace MinecraftClient.Mapping foreach (Dictionary dimensionNbt in dimensionListNbt) { string dimensionName = (string)dimensionNbt["name"]; - Dictionary element = (Dictionary)dimensionNbt["element"]; - if (dimensionList.ContainsKey(dimensionName)) - dimensionList.Remove(dimensionName); - dimensionList.Add(dimensionName, new Dimension(dimensionName, element)); + Dictionary dimensionType = (Dictionary)dimensionNbt["element"]; + StoreOneDimension(dimensionName, dimensionType); } } /// - /// Store one dimension - 1.16.2 to 1.18.2 + /// Store one dimension - Directly used in 1.16.2 to 1.18.2 /// /// Dimension name /// Dimension Type nbt data - public static void StoreDimension(string dimensionName, Dictionary dimensionType) + public static void StoreOneDimension(string dimensionName, Dictionary dimensionType) { if (dimensionList.ContainsKey(dimensionName)) dimensionList.Remove(dimensionName); diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index f60b62f4..a00011ce 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -406,7 +406,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetTerrainEnabled()) { if (protocolVersion >= MC_1_16_2_Version && protocolVersion < MC_1_19_Version) - World.StoreDimension(dimensionName, dimensionType!); + World.StoreOneDimension(dimensionName, dimensionType!); World.SetDimension(dimensionName); } } @@ -623,7 +623,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetTerrainEnabled()) { if (protocolVersion >= MC_1_16_2_Version && protocolVersion < MC_1_19_Version) - World.StoreDimension(dimensionName, dimensionTypeRespawn!); + World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); World.SetDimension(dimensionName); } } From 317f2e78a9c97499c2888c5b399653e884be4a96 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 7 Sep 2022 03:04:07 +0800 Subject: [PATCH 10/12] Rewrite adaptation algorithm --- MinecraftClient/Commands/Chunk.cs | 124 ++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 41 deletions(-) diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index a686a23a..855e5658 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -41,76 +41,118 @@ namespace MinecraftClient.Commands sb.Append(String.Format("chunk: ({0}, {1}).\n", markChunkX, markChunkZ)); } - if (markedChunkPos != null && - (markChunkX < current.ChunkX - 16 || markChunkX >= current.ChunkX + 16 || markChunkZ < current.ChunkZ - 16 || markChunkZ >= current.ChunkZ + 16)) - sb.Append("§x§0Since the marked chunk is outside the graph, it will not be displayed!§r\n"); + int consoleHeight = Math.Max(Console.BufferHeight - 2, 25); + if (consoleHeight % 2 == 0) + --consoleHeight; - int consoleHei = Math.Max(Console.BufferHeight - 2, 21); - if (consoleHei % 2 == 0) - --consoleHei; + int consoleWidth = Math.Max(Console.BufferWidth / 2, 17); + if (consoleWidth % 2 == 0) + --consoleWidth; - int consoleWid = Math.Max(Console.BufferWidth / 2, 21); - if (consoleWid % 2 == 0) - --consoleWid; - - int startZ = current.ChunkZ - consoleHei / 2, endZ = current.ChunkZ + 1 + consoleHei / 2; - int startX = current.ChunkX - consoleWid / 2, endX = current.ChunkX + 1 + consoleWid / 2; + int startZ = current.ChunkZ - consoleHeight, endZ = current.ChunkZ + consoleHeight; + int startX = current.ChunkX - consoleWidth, endX = current.ChunkX + consoleWidth; int leftMost = endX, rightMost = startX, topMost = endZ, bottomMost = startZ; - - Dictionary, byte> chunkStatus = new(); - for (int z = startZ - 1; z <= endZ + 1; z++) + for (int z = startZ; z <= endZ; z++) { - for (int x = startX - 1; x <= endX + 1; ++x) + for (int x = startX; x <= endX; ++x) { - ChunkColumn? chunkColumn = world[x, z]; - if (chunkColumn == null) - chunkStatus[new(x, z)] = 0; // "🔳" white hollow square - else + if (world[x, z] != null) { leftMost = Math.Min(leftMost, x); rightMost = Math.Max(rightMost, x); topMost = Math.Min(topMost, z); bottomMost = Math.Max(bottomMost, z); - if (chunkColumn.FullyLoaded) - chunkStatus[new(x, z)] = 1; // "🟩" green - else - chunkStatus[new(x, z)] = 2; // "🟨" yellow } } } - // Add a blank line - if (topMost != startZ) - --topMost; - if (bottomMost != endZ) - ++bottomMost; - if (Console.BufferWidth / 2 >= ((rightMost - leftMost + 1) + 2)) + // Include the player's location + topMost = Math.Min(topMost, current.ChunkZ); + bottomMost = Math.Max(bottomMost, current.ChunkZ); + leftMost = Math.Min(leftMost, current.ChunkX); + rightMost = Math.Max(rightMost, current.ChunkX); + + // Empty one row and one column each + --leftMost; ++rightMost; --topMost; ++bottomMost; + + // Resize according to limitations + if ((bottomMost - topMost + 1) > consoleHeight) { - if (leftMost != startX) - --leftMost; - if (rightMost != endX) - ++rightMost; + int delta = (bottomMost - topMost + 1) - consoleHeight; + if (bottomMost - (delta + 1) / 2 < current.ChunkZ + 1) + { + int bottomReduce = bottomMost - (current.ChunkZ + 1); + bottomMost -= bottomReduce; + topMost += delta - bottomReduce; + } + else if (topMost + delta / 2 > current.ChunkZ - 1) + { + int topAdd = topMost - (current.ChunkZ - 1); + topMost += topAdd; + bottomMost -= delta - topAdd; + } + else + { + topMost += delta / 2; + bottomMost -= (delta + 1) / 2; + } } + if ((rightMost - leftMost + 1) > consoleWidth) + { + int delta = (rightMost - leftMost + 1) - consoleWidth; + if (rightMost - (delta + 1) / 2 < current.ChunkX + 1) + { + int rightReduce = rightMost - (current.ChunkX + 1); + rightMost -= rightReduce; + leftMost += delta - rightReduce; + } + else if (leftMost + delta / 2 > current.ChunkX - 1) + { + int leftAdd = leftMost - (current.ChunkX - 1); + leftMost += leftAdd; + rightMost -= delta - leftAdd; + } + else + { + leftMost += delta / 2; + rightMost -= (delta + 1) / 2; + } + } + + // Try to include the marker chunk + if (markedChunkPos != null && + (((Math.Max(bottomMost, markChunkZ) - Math.Min(topMost, markChunkZ) + 1) > consoleHeight) || + ((Math.Max(rightMost, markChunkX) - Math.Min(leftMost, markChunkX) + 1) > consoleWidth))) + sb.Append("§x§0Since the marked chunk is outside the graph, it will not be displayed!§r\n"); else { - leftMost = Math.Max(leftMost, startX); - rightMost = Math.Min(rightMost, endX); + topMost = Math.Min(topMost, markChunkZ); + bottomMost = Math.Max(bottomMost, markChunkZ); + leftMost = Math.Min(leftMost, markChunkX); + rightMost = Math.Max(rightMost, markChunkX); } // Output - string[] chunkStatuToEmoji = new string[] { "\ud83d\udd33", "\ud83d\udfe9", "\ud83d\udfe8" }; for (int z = topMost; z <= bottomMost; ++z) { for (int x = leftMost; x <= rightMost; ++x) { if (z == current.ChunkZ && x == current.ChunkX) - sb.Append("§z"); // Player Location: background gray + sb.Append("§z"); // Player Location: background gray else if (z == markChunkZ && x == markChunkX) - sb.Append("§w"); // Marked chunk: background red - sb.Append(chunkStatuToEmoji[chunkStatus.GetValueOrDefault, byte>(new(x, z), 0)]); + sb.Append("§w"); // Marked chunk: background red + + ChunkColumn? chunkColumn = world[x, z]; + if (chunkColumn == null) + sb.Append("\ud83d\udd33"); // "🔳" white hollow square + else if (chunkColumn.FullyLoaded) + sb.Append("\ud83d\udfe9"); // "🟩" green + else + sb.Append("\ud83d\udfe8"); // "🟨" yellow + if ((z == current.ChunkZ && x == current.ChunkX) || (z == markChunkZ && x == markChunkX)) - sb.Append("§r"); + sb.Append("§r"); // Reset background color } sb.Append('\n'); } From c5d52879383cd692c196b00d6ef47e4b063772ee Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 7 Sep 2022 17:25:06 +0800 Subject: [PATCH 11/12] Improve IsOnGround --- MinecraftClient/Mapping/MaterialExtensions.cs | 196 ++++++++++++++++-- MinecraftClient/Mapping/Movement.cs | 32 ++- 2 files changed, 208 insertions(+), 20 deletions(-) diff --git a/MinecraftClient/Mapping/MaterialExtensions.cs b/MinecraftClient/Mapping/MaterialExtensions.cs index d10913c2..cf29dd71 100644 --- a/MinecraftClient/Mapping/MaterialExtensions.cs +++ b/MinecraftClient/Mapping/MaterialExtensions.cs @@ -19,32 +19,40 @@ namespace MinecraftClient.Mapping { switch (m) { + case Material.AcaciaDoor: case Material.AcaciaFence: case Material.AcaciaFenceGate: case Material.AcaciaLeaves: case Material.AcaciaLog: case Material.AcaciaPlanks: + case Material.AcaciaPressurePlate: + case Material.AcaciaSign: case Material.AcaciaSlab: case Material.AcaciaStairs: case Material.AcaciaTrapdoor: + case Material.AcaciaWallSign: case Material.AcaciaWood: case Material.AmethystBlock: case Material.AmethystCluster: + case Material.AncientDebris: case Material.Andesite: case Material.AndesiteSlab: case Material.AndesiteStairs: case Material.AndesiteWall: case Material.Anvil: + case Material.AttachedMelonStem: + case Material.AttachedPumpkinStem: case Material.Azalea: case Material.AzaleaLeaves: case Material.Bamboo: + case Material.BambooSapling: case Material.Barrel: case Material.Barrier: case Material.Basalt: case Material.Beacon: case Material.Bedrock: - case Material.BeeNest: case Material.Beehive: + case Material.BeeNest: case Material.Bell: case Material.BirchDoor: case Material.BirchFence: @@ -52,10 +60,14 @@ namespace MinecraftClient.Mapping case Material.BirchLeaves: case Material.BirchLog: case Material.BirchPlanks: + case Material.BirchPressurePlate: + case Material.BirchSign: case Material.BirchSlab: case Material.BirchStairs: case Material.BirchTrapdoor: + case Material.BirchWallSign: case Material.BirchWood: + case Material.BlackBanner: case Material.BlackBed: case Material.BlackCandle: case Material.BlackCandleCake: @@ -68,9 +80,12 @@ namespace MinecraftClient.Mapping case Material.Blackstone: case Material.BlackstoneSlab: case Material.BlackstoneStairs: + case Material.BlackstoneWall: case Material.BlackTerracotta: + case Material.BlackWallBanner: case Material.BlackWool: case Material.BlastFurnace: + case Material.BlueBanner: case Material.BlueBed: case Material.BlueCandle: case Material.BlueCandleCake: @@ -82,15 +97,17 @@ namespace MinecraftClient.Mapping case Material.BlueStainedGlass: case Material.BlueStainedGlassPane: case Material.BlueTerracotta: + case Material.BlueWallBanner: case Material.BlueWool: case Material.BoneBlock: case Material.Bookshelf: case Material.BrainCoralBlock: case Material.BrewingStand: + case Material.Bricks: case Material.BrickSlab: case Material.BrickStairs: case Material.BrickWall: - case Material.Bricks: + case Material.BrownBanner: case Material.BrownBed: case Material.BrownCandle: case Material.BrownCandleCake: @@ -102,6 +119,7 @@ namespace MinecraftClient.Mapping case Material.BrownStainedGlass: case Material.BrownStainedGlassPane: case Material.BrownTerracotta: + case Material.BrownWallBanner: case Material.BrownWool: case Material.BubbleColumn: case Material.BubbleCoralBlock: @@ -115,10 +133,13 @@ namespace MinecraftClient.Mapping case Material.CartographyTable: case Material.CarvedPumpkin: case Material.Cauldron: + case Material.Chain: case Material.ChainCommandBlock: case Material.Chest: case Material.ChippedAnvil: case Material.ChiseledDeepslate: + case Material.ChiseledNetherBricks: + case Material.ChiseledPolishedBlackstone: case Material.ChiseledQuartzBlock: case Material.ChiseledRedSandstone: case Material.ChiseledSandstone: @@ -137,6 +158,7 @@ namespace MinecraftClient.Mapping case Material.CobblestoneSlab: case Material.CobblestoneStairs: case Material.CobblestoneWall: + case Material.Cobweb: case Material.CommandBlock: case Material.Composter: case Material.Conduit: @@ -144,10 +166,26 @@ namespace MinecraftClient.Mapping case Material.CopperOre: case Material.CrackedDeepslateBricks: case Material.CrackedDeepslateTiles: + case Material.CrackedNetherBricks: + case Material.CrackedPolishedBlackstoneBricks: case Material.CrackedStoneBricks: case Material.CraftingTable: case Material.CreeperHead: case Material.CreeperWallHead: + case Material.CrimsonDoor: + case Material.CrimsonFence: + case Material.CrimsonFenceGate: + case Material.CrimsonHyphae: + case Material.CrimsonNylium: + case Material.CrimsonPlanks: + case Material.CrimsonPressurePlate: + case Material.CrimsonSign: + case Material.CrimsonSlab: + case Material.CrimsonStairs: + case Material.CrimsonStem: + case Material.CrimsonTrapdoor: + case Material.CrimsonWallSign: + case Material.CryingObsidian: case Material.CutCopper: case Material.CutCopperSlab: case Material.CutCopperStairs: @@ -155,6 +193,7 @@ namespace MinecraftClient.Mapping case Material.CutRedSandstoneSlab: case Material.CutSandstone: case Material.CutSandstoneSlab: + case Material.CyanBanner: case Material.CyanBed: case Material.CyanCandle: case Material.CyanCandleCake: @@ -165,6 +204,7 @@ namespace MinecraftClient.Mapping case Material.CyanStainedGlass: case Material.CyanStainedGlassPane: case Material.CyanTerracotta: + case Material.CyanWallBanner: case Material.CyanWool: case Material.DamagedAnvil: case Material.DarkOakDoor: @@ -173,29 +213,54 @@ namespace MinecraftClient.Mapping case Material.DarkOakLeaves: case Material.DarkOakLog: case Material.DarkOakPlanks: + case Material.DarkOakPressurePlate: + case Material.DarkOakSign: case Material.DarkOakSlab: case Material.DarkOakStairs: case Material.DarkOakTrapdoor: + case Material.DarkOakWallSign: case Material.DarkOakWood: case Material.DarkPrismarine: case Material.DarkPrismarineSlab: case Material.DarkPrismarineStairs: case Material.DaylightDetector: + case Material.DeadBrainCoral: case Material.DeadBrainCoralBlock: + case Material.DeadBrainCoralFan: + case Material.DeadBrainCoralWallFan: + case Material.DeadBubbleCoral: case Material.DeadBubbleCoralBlock: + case Material.DeadBubbleCoralFan: + case Material.DeadBubbleCoralWallFan: + case Material.DeadFireCoral: case Material.DeadFireCoralBlock: + case Material.DeadFireCoralFan: + case Material.DeadFireCoralWallFan: + case Material.DeadHornCoral: case Material.DeadHornCoralBlock: + case Material.DeadHornCoralFan: + case Material.DeadHornCoralWallFan: + case Material.DeadTubeCoral: case Material.DeadTubeCoralBlock: + case Material.DeadTubeCoralFan: + case Material.DeadTubeCoralWallFan: case Material.Deepslate: + case Material.DeepslateBricks: case Material.DeepslateBrickSlab: case Material.DeepslateBrickStairs: case Material.DeepslateBrickWall: - case Material.DeepslateBricks: + case Material.DeepslateCoalOre: case Material.DeepslateCopperOre: + case Material.DeepslateDiamondOre: + case Material.DeepslateEmeraldOre: + case Material.DeepslateGoldOre: + case Material.DeepslateIronOre: + case Material.DeepslateLapisOre: + case Material.DeepslateRedstoneOre: + case Material.DeepslateTiles: case Material.DeepslateTileSlab: case Material.DeepslateTileStairs: case Material.DeepslateTileWall: - case Material.DeepslateTiles: case Material.DiamondBlock: case Material.DiamondOre: case Material.Diorite: @@ -214,14 +279,14 @@ namespace MinecraftClient.Mapping case Material.EmeraldBlock: case Material.EmeraldOre: case Material.EnchantingTable: + case Material.EnderChest: case Material.EndPortalFrame: case Material.EndRod: case Material.EndStone: + case Material.EndStoneBricks: case Material.EndStoneBrickSlab: case Material.EndStoneBrickStairs: case Material.EndStoneBrickWall: - case Material.EndStoneBricks: - case Material.EnderChest: case Material.ExposedCopper: case Material.ExposedCutCopper: case Material.ExposedCutCopperSlab: @@ -229,11 +294,12 @@ namespace MinecraftClient.Mapping case Material.Farmland: case Material.FireCoralBlock: case Material.FletchingTable: - case Material.FlowerPot: case Material.FloweringAzalea: case Material.FloweringAzaleaLeaves: + case Material.FlowerPot: case Material.FrostedIce: case Material.Furnace: + case Material.GildedBlackstone: case Material.Glass: case Material.GlassPane: case Material.Glowstone: @@ -245,6 +311,7 @@ namespace MinecraftClient.Mapping case Material.GraniteWall: case Material.GrassBlock: case Material.Gravel: + case Material.GrayBanner: case Material.GrayBed: case Material.GrayCandle: case Material.GrayCandleCake: @@ -255,7 +322,9 @@ namespace MinecraftClient.Mapping case Material.GrayStainedGlass: case Material.GrayStainedGlassPane: case Material.GrayTerracotta: + case Material.GrayWallBanner: case Material.GrayWool: + case Material.GreenBanner: case Material.GreenBed: case Material.GreenCandle: case Material.GreenCandleCake: @@ -266,9 +335,11 @@ namespace MinecraftClient.Mapping case Material.GreenStainedGlass: case Material.GreenStainedGlassPane: case Material.GreenTerracotta: + case Material.GreenWallBanner: case Material.GreenWool: case Material.Grindstone: case Material.HayBlock: + case Material.HeavyWeightedPressurePlate: case Material.HoneyBlock: case Material.HoneycombBlock: case Material.Hopper: @@ -295,9 +366,12 @@ namespace MinecraftClient.Mapping case Material.JungleLeaves: case Material.JungleLog: case Material.JunglePlanks: + case Material.JunglePressurePlate: + case Material.JungleSign: case Material.JungleSlab: case Material.JungleStairs: case Material.JungleTrapdoor: + case Material.JungleWallSign: case Material.JungleWood: case Material.Ladder: case Material.Lantern: @@ -306,6 +380,7 @@ namespace MinecraftClient.Mapping case Material.LargeAmethystBud: case Material.LavaCauldron: case Material.Lectern: + case Material.LightBlueBanner: case Material.LightBlueBed: case Material.LightBlueCandle: case Material.LightBlueCandleCake: @@ -316,7 +391,9 @@ namespace MinecraftClient.Mapping case Material.LightBlueStainedGlass: case Material.LightBlueStainedGlassPane: case Material.LightBlueTerracotta: + case Material.LightBlueWallBanner: case Material.LightBlueWool: + case Material.LightGrayBanner: case Material.LightGrayBed: case Material.LightGrayCandle: case Material.LightGrayCandleCake: @@ -327,9 +404,12 @@ namespace MinecraftClient.Mapping case Material.LightGrayStainedGlass: case Material.LightGrayStainedGlassPane: case Material.LightGrayTerracotta: + case Material.LightGrayWallBanner: case Material.LightGrayWool: case Material.LightningRod: + case Material.LightWeightedPressurePlate: case Material.LilyPad: + case Material.LimeBanner: case Material.LimeBed: case Material.LimeCandle: case Material.LimeCandleCake: @@ -340,8 +420,11 @@ namespace MinecraftClient.Mapping case Material.LimeStainedGlass: case Material.LimeStainedGlassPane: case Material.LimeTerracotta: + case Material.LimeWallBanner: case Material.LimeWool: + case Material.Lodestone: case Material.Loom: + case Material.MagentaBanner: case Material.MagentaBed: case Material.MagentaCandle: case Material.MagentaCandleCake: @@ -352,39 +435,55 @@ namespace MinecraftClient.Mapping case Material.MagentaStainedGlass: case Material.MagentaStainedGlassPane: case Material.MagentaTerracotta: + case Material.MagentaWallBanner: case Material.MagentaWool: case Material.MagmaBlock: + case Material.MangroveDoor: + case Material.MangroveFence: + case Material.MangroveFenceGate: case Material.MangroveLeaves: case Material.MangroveLog: case Material.MangrovePlanks: case Material.MangrovePressurePlate: case Material.MangroveRoots: + case Material.MangroveSign: case Material.MangroveSlab: case Material.MangroveStairs: + case Material.MangroveTrapdoor: + case Material.MangroveWallSign: case Material.MangroveWood: case Material.MediumAmethystBud: case Material.Melon: + case Material.MelonStem: case Material.MossBlock: case Material.MossCarpet: case Material.MossyCobblestone: case Material.MossyCobblestoneSlab: case Material.MossyCobblestoneStairs: case Material.MossyCobblestoneWall: + case Material.MossyStoneBricks: case Material.MossyStoneBrickSlab: case Material.MossyStoneBrickStairs: case Material.MossyStoneBrickWall: - case Material.MossyStoneBricks: case Material.MovingPiston: + case Material.Mud: + case Material.MudBricks: + case Material.MudBrickSlab: + case Material.MudBrickStairs: + case Material.MudBrickWall: + case Material.MuddyMangroveRoots: case Material.MushroomStem: case Material.Mycelium: case Material.NetherBrickFence: + case Material.NetherBricks: case Material.NetherBrickSlab: case Material.NetherBrickStairs: case Material.NetherBrickWall: - case Material.NetherBricks: + case Material.NetherGoldOre: + case Material.NetheriteBlock: case Material.NetherQuartzOre: - case Material.NetherWartBlock: case Material.Netherrack: + case Material.NetherWartBlock: case Material.NoteBlock: case Material.OakDoor: case Material.OakFence: @@ -392,12 +491,17 @@ namespace MinecraftClient.Mapping case Material.OakLeaves: case Material.OakLog: case Material.OakPlanks: + case Material.OakPressurePlate: + case Material.OakSign: case Material.OakSlab: case Material.OakStairs: case Material.OakTrapdoor: + case Material.OakWallSign: case Material.OakWood: case Material.Observer: case Material.Obsidian: + case Material.OchreFroglight: + case Material.OrangeBanner: case Material.OrangeBed: case Material.OrangeCandle: case Material.OrangeCandleCake: @@ -408,13 +512,17 @@ namespace MinecraftClient.Mapping case Material.OrangeStainedGlass: case Material.OrangeStainedGlassPane: case Material.OrangeTerracotta: + case Material.OrangeWallBanner: case Material.OrangeWool: case Material.OxidizedCopper: case Material.OxidizedCutCopper: case Material.OxidizedCutCopperSlab: case Material.OxidizedCutCopperStairs: case Material.PackedIce: + case Material.PackedMud: + case Material.PearlescentFroglight: case Material.PetrifiedOakSlab: + case Material.PinkBanner: case Material.PinkBed: case Material.PinkCandle: case Material.PinkCandleCake: @@ -425,6 +533,7 @@ namespace MinecraftClient.Mapping case Material.PinkStainedGlass: case Material.PinkStainedGlassPane: case Material.PinkTerracotta: + case Material.PinkWallBanner: case Material.PinkWool: case Material.Piston: case Material.PistonHead: @@ -436,6 +545,15 @@ namespace MinecraftClient.Mapping case Material.PolishedAndesiteSlab: case Material.PolishedAndesiteStairs: case Material.PolishedBasalt: + case Material.PolishedBlackstone: + case Material.PolishedBlackstoneBricks: + case Material.PolishedBlackstoneBrickSlab: + case Material.PolishedBlackstoneBrickStairs: + case Material.PolishedBlackstoneBrickWall: + case Material.PolishedBlackstonePressurePlate: + case Material.PolishedBlackstoneSlab: + case Material.PolishedBlackstoneStairs: + case Material.PolishedBlackstoneWall: case Material.PolishedDeepslate: case Material.PolishedDeepslateSlab: case Material.PolishedDeepslateStairs: @@ -475,13 +593,15 @@ namespace MinecraftClient.Mapping case Material.PottedWitherRose: case Material.PowderSnowCauldron: case Material.Prismarine: + case Material.PrismarineBricks: case Material.PrismarineBrickSlab: case Material.PrismarineBrickStairs: - case Material.PrismarineBricks: case Material.PrismarineSlab: case Material.PrismarineStairs: case Material.PrismarineWall: case Material.Pumpkin: + case Material.PumpkinStem: + case Material.PurpleBanner: case Material.PurpleBed: case Material.PurpleCandle: case Material.PurpleCandleCake: @@ -492,18 +612,21 @@ namespace MinecraftClient.Mapping case Material.PurpleStainedGlass: case Material.PurpleStainedGlassPane: case Material.PurpleTerracotta: + case Material.PurpleWallBanner: case Material.PurpleWool: case Material.PurpurBlock: case Material.PurpurPillar: case Material.PurpurSlab: case Material.PurpurStairs: case Material.QuartzBlock: + case Material.QuartzBricks: case Material.QuartzPillar: case Material.QuartzSlab: case Material.QuartzStairs: case Material.RawCopperBlock: case Material.RawGoldBlock: case Material.RawIronBlock: + case Material.RedBanner: case Material.RedBed: case Material.RedCandle: case Material.RedCandleCake: @@ -511,10 +634,10 @@ namespace MinecraftClient.Mapping case Material.RedConcretePowder: case Material.RedGlazedTerracotta: case Material.RedMushroomBlock: + case Material.RedNetherBricks: case Material.RedNetherBrickSlab: case Material.RedNetherBrickStairs: case Material.RedNetherBrickWall: - case Material.RedNetherBricks: case Material.RedSand: case Material.RedSandstone: case Material.RedSandstoneSlab: @@ -523,21 +646,29 @@ namespace MinecraftClient.Mapping case Material.RedShulkerBox: case Material.RedStainedGlass: case Material.RedStainedGlassPane: - case Material.RedTerracotta: - case Material.RedWool: case Material.RedstoneBlock: case Material.RedstoneLamp: case Material.RedstoneOre: + case Material.RedTerracotta: + case Material.RedWallBanner: + case Material.RedWool: + case Material.ReinforcedDeepslate: case Material.RepeatingCommandBlock: + case Material.RespawnAnchor: case Material.RootedDirt: case Material.Sand: case Material.Sandstone: case Material.SandstoneSlab: case Material.SandstoneStairs: case Material.SandstoneWall: + case Material.Sculk: + case Material.SculkCatalyst: case Material.SculkSensor: + case Material.SculkShrieker: + case Material.SculkVein: case Material.SeaLantern: case Material.SeaPickle: + case Material.Shroomlight: case Material.ShulkerBox: case Material.SkeletonSkull: case Material.SkeletonWallSkull: @@ -558,6 +689,8 @@ namespace MinecraftClient.Mapping case Material.SmoothStone: case Material.SmoothStoneSlab: case Material.SnowBlock: + case Material.SoulCampfire: + case Material.SoulLantern: case Material.SoulSand: case Material.SoulSoil: case Material.Spawner: @@ -568,32 +701,43 @@ namespace MinecraftClient.Mapping case Material.SpruceLeaves: case Material.SpruceLog: case Material.SprucePlanks: + case Material.SprucePressurePlate: + case Material.SpruceSign: case Material.SpruceSlab: case Material.SpruceStairs: case Material.SpruceTrapdoor: + case Material.SpruceWallSign: case Material.SpruceWood: case Material.StickyPiston: case Material.Stone: + case Material.StoneBricks: case Material.StoneBrickSlab: case Material.StoneBrickStairs: case Material.StoneBrickWall: - case Material.StoneBricks: + case Material.Stonecutter: + case Material.StonePressurePlate: case Material.StoneSlab: case Material.StoneStairs: - case Material.Stonecutter: case Material.StrippedAcaciaLog: case Material.StrippedAcaciaWood: case Material.StrippedBirchLog: case Material.StrippedBirchWood: + case Material.StrippedCrimsonHyphae: + case Material.StrippedCrimsonStem: case Material.StrippedDarkOakLog: case Material.StrippedDarkOakWood: case Material.StrippedJungleLog: case Material.StrippedJungleWood: + case Material.StrippedMangroveLog: + case Material.StrippedMangroveWood: case Material.StrippedOakLog: case Material.StrippedOakWood: case Material.StrippedSpruceLog: case Material.StrippedSpruceWood: + case Material.StrippedWarpedHyphae: + case Material.StrippedWarpedStem: case Material.StructureBlock: + case Material.Target: case Material.Terracotta: case Material.TintedGlass: case Material.Tnt: @@ -601,6 +745,21 @@ namespace MinecraftClient.Mapping case Material.TubeCoralBlock: case Material.Tuff: case Material.TurtleEgg: + case Material.VerdantFroglight: + case Material.WarpedDoor: + case Material.WarpedFence: + case Material.WarpedFenceGate: + case Material.WarpedHyphae: + case Material.WarpedNylium: + case Material.WarpedPlanks: + case Material.WarpedPressurePlate: + case Material.WarpedSign: + case Material.WarpedSlab: + case Material.WarpedStairs: + case Material.WarpedStem: + case Material.WarpedTrapdoor: + case Material.WarpedWallSign: + case Material.WarpedWartBlock: case Material.WaterCauldron: case Material.WaxedCopperBlock: case Material.WaxedCutCopper: @@ -623,6 +782,7 @@ namespace MinecraftClient.Mapping case Material.WeatheredCutCopperSlab: case Material.WeatheredCutCopperStairs: case Material.WetSponge: + case Material.WhiteBanner: case Material.WhiteBed: case Material.WhiteCandle: case Material.WhiteCandleCake: @@ -633,9 +793,11 @@ namespace MinecraftClient.Mapping case Material.WhiteStainedGlass: case Material.WhiteStainedGlassPane: case Material.WhiteTerracotta: + case Material.WhiteWallBanner: case Material.WhiteWool: case Material.WitherSkeletonSkull: case Material.WitherSkeletonWallSkull: + case Material.YellowBanner: case Material.YellowBed: case Material.YellowCandle: case Material.YellowCandleCake: @@ -646,10 +808,10 @@ namespace MinecraftClient.Mapping case Material.YellowStainedGlass: case Material.YellowStainedGlassPane: case Material.YellowTerracotta: + case Material.YellowWallBanner: case Material.YellowWool: case Material.ZombieHead: case Material.ZombieWallHead: - case Material.AcaciaDoor: return true; default: return false; diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs index 97af6359..5cde8624 100644 --- a/MinecraftClient/Mapping/Movement.cs +++ b/MinecraftClient/Mapping/Movement.cs @@ -462,11 +462,37 @@ namespace MinecraftClient.Mapping /// True if the specified location is on the ground public static bool IsOnGround(World world, Location location) { - if (world.GetChunkColumn(location) == null || world.GetChunkColumn(location).FullyLoaded == false) + ChunkColumn? chunkColumn = world.GetChunkColumn(location); + if (chunkColumn == null || chunkColumn.FullyLoaded == false) return true; // avoid moving downward in a not loaded chunk - return world.GetBlock(Move(location, Direction.Down)).Type.IsSolid() - && (location.Y <= Math.Truncate(location.Y) + 0.0001); + Location down = Move(location, Direction.Down); + + bool result = world.GetBlock(down).Type.IsSolid(); + + bool northCheck = 1 + Math.Floor(down.Z) - down.Z > 0.7; + bool eastCheck = down.X - Math.Floor(down.X) > 0.7; + bool southCheck = down.Z - Math.Floor(down.Z) > 0.7; + bool westCheck = 1 + Math.Floor(down.X) - down.X > 0.7; + + if (!result && northCheck) + result |= world.GetBlock(Move(down, Direction.North)).Type.IsSolid(); + if (!result && northCheck && eastCheck) + result |= world.GetBlock(Move(down, Direction.NorthEast)).Type.IsSolid(); + if (!result && eastCheck) + result |= world.GetBlock(Move(down, Direction.East)).Type.IsSolid(); + if (!result && eastCheck && southCheck) + result |= world.GetBlock(Move(down, Direction.SouthEast)).Type.IsSolid(); + if (!result && southCheck) + result |= world.GetBlock(Move(down, Direction.South)).Type.IsSolid(); + if (!result && southCheck && westCheck) + result |= world.GetBlock(Move(down, Direction.SouthWest)).Type.IsSolid(); + if (!result && westCheck) + result |= world.GetBlock(Move(down, Direction.West)).Type.IsSolid(); + if (!result && westCheck && northCheck) + result |= world.GetBlock(Move(down, Direction.NorthWest)).Type.IsSolid(); + + return result && (location.Y <= Math.Truncate(location.Y) + 0.0001); } /// From c3d1b4e2ea18857664d0a3c9726f274639559bd8 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Wed, 7 Sep 2022 18:19:03 +0800 Subject: [PATCH 12/12] Update ConsoleInteractive --- ConsoleInteractive | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ConsoleInteractive b/ConsoleInteractive index a5ed69ef..b4fd7da2 160000 --- a/ConsoleInteractive +++ b/ConsoleInteractive @@ -1 +1 @@ -Subproject commit a5ed69efcf6a8803a8f5c3c10501266cd21947c7 +Subproject commit b4fd7da2595ad54479880fc1c9c6e14975412d92