From ff1c570a783fc4df1adb741d64e8efb0c7f2f5a7 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:11:13 +0800 Subject: [PATCH] Handle non-interactive terminal environments gracefully When MCC runs in non-interactive terminals (e.g. CI runners, IDE embedded shells, piped input), several Console APIs throw exceptions because there is no real console attached. Changes: - Program.cs: Wrap Console.KeyAvailable / Console.ReadKey in HandleFailure() with try-catch so MCC does not crash on startup failure in headless environments. - Chunk.cs: Wrap Console.BufferWidth / BufferHeight in try-catch with fallback values (120x50) to prevent exceptions when rendering chunk maps without a console buffer. - Map.cs: Same treatment for the map rendering path - use safe fallback values when Console.BufferWidth/Height are unavailable. - ReplayHandler.cs: Replace Array.Reverse() (returns void in newer .NET) with .AsEnumerable().Reverse() to fix compilation with .NET 10 SDK where the void return breaks the fluent chain. Made-with: Cursor --- MinecraftClient/ChatBots/Map.cs | 9 ++++++--- MinecraftClient/Commands/Chunk.cs | 10 +++++++--- MinecraftClient/Program.cs | 8 +++++--- MinecraftClient/Protocol/ReplayHandler.cs | 6 +++--- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/MinecraftClient/ChatBots/Map.cs b/MinecraftClient/ChatBots/Map.cs index 25e75a74..c0c3aa8e 100644 --- a/MinecraftClient/ChatBots/Map.cs +++ b/MinecraftClient/ChatBots/Map.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -344,8 +344,11 @@ namespace MinecraftClient.ChatBots private static void RenderInConsole(McMap map) { StringBuilder sb = new(); - int consoleWidth = Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2; - int consoleHeight = Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 1; + int safeBufWidth, safeBufHeight; + try { safeBufWidth = Console.BufferWidth; } catch { safeBufWidth = 120; } + try { safeBufHeight = Console.BufferHeight; } catch { safeBufHeight = 50; } + int consoleWidth = Math.Max(safeBufWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2; + int consoleHeight = Math.Max(safeBufHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 1; int scaleX = (map.Width + consoleWidth - 1) / consoleWidth; int scaleY = (map.Height + consoleHeight - 1) / consoleHeight; int scale = Math.Max(scaleX, scaleY); diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index cdc26e14..2068c662 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Brigadier.NET; using Brigadier.NET.Builder; @@ -100,11 +100,15 @@ namespace MinecraftClient.Commands sb.AppendLine(string.Format(Translations.cmd_chunk_chunk_pos, markChunkX, markChunkZ)); ; } - int consoleHeight = Math.Max(Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25); + int safeHeight; + int safeWidth; + try { safeHeight = Console.BufferHeight; } catch { safeHeight = 50; } + try { safeWidth = Console.BufferWidth; } catch { safeWidth = 120; } + int consoleHeight = Math.Max(Math.Max(safeHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25); if (consoleHeight % 2 == 0) --consoleHeight; - int consoleWidth = Math.Max(Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17); + int consoleWidth = Math.Max(Math.Max(safeWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17); if (consoleWidth % 2 == 0) --consoleWidth; diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 1b68583d..b8a1f788 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -768,8 +768,10 @@ namespace MinecraftClient if (!String.IsNullOrEmpty(errorMessage)) { ConsoleIO.Reset(); - while (Console.KeyAvailable) - Console.ReadKey(true); + try { + while (Console.KeyAvailable) + Console.ReadKey(true); + } catch { } ConsoleIO.WriteLine(errorMessage); if (disconnectReason.HasValue) diff --git a/MinecraftClient/Protocol/ReplayHandler.cs b/MinecraftClient/Protocol/ReplayHandler.cs index 75184e26..be567caf 100644 --- a/MinecraftClient/Protocol/ReplayHandler.cs +++ b/MinecraftClient/Protocol/ReplayHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -239,8 +239,8 @@ namespace MinecraftClient.Protocol // format: timestamp + packetLength + RawPacket List line = new(); int nowTime = Convert.ToInt32((lastPacketTime - recordStartTime).TotalMilliseconds); - line.AddRange(BitConverter.GetBytes((Int32)nowTime).Reverse().ToArray()); - line.AddRange(BitConverter.GetBytes((Int32)rawPacket.Count).Reverse().ToArray()); + line.AddRange(BitConverter.GetBytes((Int32)nowTime).AsEnumerable().Reverse().ToArray()); + line.AddRange(BitConverter.GetBytes((Int32)rawPacket.Count).AsEnumerable().Reverse().ToArray()); line.AddRange(rawPacket.ToArray()); // Write out to the file recordStream!.Write(line.ToArray());