breadbyte / ConsoleInteractive

a user input library for c#
Apache License 2.0
6 stars 3 forks source link

Exception when running ConsoleInteractive in a Docker environment #9

Closed breadbyte closed 1 year ago

breadbyte commented 2 years ago

On a Docker Environment, Console.BufferWidth and Console.BufferHeight both return 0.

This causes some internal math logic for cursor positioning in InternalContext to go awry.

The fix for this is on a similar vein as #8, as .NET recognizes that the input/output is being redirected and thus requires the use of Console.IsInputRedirected and Console.IsOutputRedirected.

milutinke commented 2 years ago

Try using the method for detecting docker environment and setting some arbitrary screen size manually so we can test it out. My guess it that it's gonna fix it. Eg. something like 120x300

CAMOBAP commented 1 year ago

@milutinke unfortunately Console.SetBufferSize will not work. This call will throw:

Unhandled Exception: System.PlatformNotSupportedException: Operation is not supported on this platform.

There is a similar issue reported for MacOS https://github.com/dotnet/runtime/issues/27216

With this changes I was managed to get MinecraftClietn work in container (docker-compose + portainer)

Diff ```diff diff --git a/ConsoleInteractive/ConsoleInteractive/ConsoleBuffer.cs b/ConsoleInteractive/ConsoleInteractive/ConsoleBuffer.cs index 06e3f63..5142b12 100644 --- a/ConsoleInteractive/ConsoleInteractive/ConsoleBuffer.cs +++ b/ConsoleInteractive/ConsoleInteractive/ConsoleBuffer.cs @@ -97,7 +97,12 @@ namespace ConsoleInteractive { /// /// Console width is actually 0 indexed, so we need to subtract 1 from the width. /// - internal static int UserInputBufferMaxLength { get { return Console.BufferWidth - 1 - PrefixTotalLength; } } + internal static int UserInputBufferMaxLength { + get { + int result = Console.BufferWidth - 1 - PrefixTotalLength; + return result > 0 ? result : 0; + } + } /// /// Stores the contents of the input area at the time of the last call to redraw. diff --git a/ConsoleInteractive/ConsoleInteractive/ConsoleWriter.cs b/ConsoleInteractive/ConsoleInteractive/ConsoleWriter.cs index fa7c49c..dd24f89 100644 --- a/ConsoleInteractive/ConsoleInteractive/ConsoleWriter.cs +++ b/ConsoleInteractive/ConsoleInteractive/ConsoleWriter.cs @@ -9,11 +9,16 @@ namespace ConsoleInteractive { public static class ConsoleWriter { public static bool EnableColor { get; set; } = true; public static bool UseVT100ColorCode { get; set; } = false; + private static bool InDocker { get { return Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";} } + private static IWriter BackendWriter = new InternalWriter(); + public static void Init() { SetWindowsConsoleAnsi(); if (!Console.IsOutputRedirected) Console.Clear(); + if (InDocker) + BackendWriter = new FallbackWriter(); } private static void SetWindowsConsoleAnsi() { @@ -24,20 +29,36 @@ namespace ConsoleInteractive { } public static void WriteLine(string value) { - InternalWriter.WriteLine(value); + BackendWriter.WriteLine(value); } public static void WriteLineFormatted(string value) { - InternalWriter.WriteLineFormatted(value); + BackendWriter.WriteLineFormatted(value); } } - internal static class InternalWriter { + internal interface IWriter { + public abstract void WriteLine(string value); + + public abstract void WriteLineFormatted(string value); + } + + internal class FallbackWriter : IWriter { + public void WriteLine(string value) { + Console.WriteLine(value); + } + + public void WriteLineFormatted(string value) { + Console.WriteLine(value); + } + } + + internal class InternalWriter : IWriter { /// /// Gets the number of lines and the width of the first line of the message. /// - private static Tuple GetLineCountInTerminal(string value) { + private Tuple GetLineCountInTerminal(string value) { if (Console.IsOutputRedirected) return new(0, 0); @@ -103,7 +124,7 @@ namespace ConsoleInteractive { } } - private static void Write(string value, List>? colors = null) { + private void Write(string value, List>? colors = null) { (int linesAdded, int firstLineLength) = GetLineCountInTerminal(value); lock (InternalContext.WriteLock) { @@ -128,11 +149,11 @@ namespace ConsoleInteractive { } } - public static void WriteLine(string value) { + public void WriteLine(string value) { Write(value); } - public static void WriteLineFormatted(string value) { + public void WriteLineFormatted(string value) { if (!ConsoleWriter.EnableColor) { Write(InternalContext.FormatRegex.Replace(value, string.Empty)); return; ```

But I see another issue with logging PrintUserInput it looks broken (or it just log binary) here is snippet

MinecraftClient output ```log Minecraft Console Client v1.20.1 - for MC 1.4.6 to 1.20.1 - Github.com/MCCTeam §8Cached session is still valid for TestUser. Using Minecraft version 1.20.1 (protocol v763) §8Cached profile key is still valid for TestUser. §8[MCC] Version is supported. Logging in... §8[MCC] Checking Session... §8[MCC] Server was successfully joined. Type '/quit' to leave the server. > Input: P��H���Up������UPW[|<-- < Input: P��H���Up������UPW[J��U(�� ����m5�U��(��P����m5�U����i5�U��i5�U��x�m5�U�|4�U0�i5�U���8g���U���������b�5�U�,���U8����U��q5�U0�i5�U���1J��U�V��J��U�b�5�U �������J��U�V��J��U��m5�U��8��`����m5�U����i5�U��i5�U|<-- > Input: U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U��|<-- §2▌§r P��H���Up������UPW[J��U(�� ����m5�U��(��P����m5�U����i5�U��i5�U��x�m5�U�|4�U0�i5�U���8g���U���������b�5�U�,���U8����U��q5�U0�i5�U���1J��U�V��J��U�b�5�U �������J��U�V��J��U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U��i5���U|<-- < Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U����@���um5�U��m5�U��m5�U����������m5�U����i5�U��i5�U���x�m5�U1���(��!���������y���U�����U����i5��UInput: UInput: U�:�<�E�_##����������������`����m5�U����i5�U��i5�U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U����@���um5�U��m5�U��m5�U����������m5�U����i5�U��i5�U���x�m5�U1���(��!���������y���U�����U����i5��UInput: UInput: U�:�<�E�_##����������������`����m5�U����i5�U��i5�U��x�m5�U t��U����8X���U ��(����U��i5�����,���U8�U1���(��8�,���U8�|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U����@���um5�U��m5�U��m5�U����������m5�U����i5�U��i5�U���x�m5�U1���(��!���������y���U�����U����i5��UInput: UInput: U�:�<�E�_##����������������`����m5�U����i5�U��i5�U��x�m5�U t��U����8X���U ��(����U��i5�����,���U8�U1���(��8�,���U8���`��P����U�|��U@���U`��U�7�U��i5�U��i5�U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U����@���um5�U��m5�U��m5�U����������m5�U����i5�U��i5�U���x�m5�U1���(��!���������y���U�����U����i5��UInput: UInput: U�:�<�E�_##����������������`����m5�U����i5�U��i5�U��x�m5�U t��U����8X���U ��(����U��i5�����,���U8�U1���(��8�,���U8���`��P����U�|��U@���U`��U�7�U��i5�U��i5�U��x�m5�Um5���U1���������(������!���������������������������y���������U���������������U������������i5������UInput: UInput: ��X���U���(����U�um5�U`��U�7�U��i5�U��i5�U|<-- Input: U�������U�U�U������ n5�U0�k�� t��U0X���U����U����U��m5�U��8��`����m5�U����i5�U��i5�U��x�m5�U����U����Ux���U�,���U���,���U@��x���U�����U����@���um5�U��m5�U��m5�U����������m5�U����i5�U��i5�U���x�m5�U1���(��!���������y���U�����U����i5��UInput: UInput: U�:�<�E�_##����������������`����m5�U����i5�U��i5�U��x�m5�U t��U����8X���U ��(����U��i5�����,���U8�U1���(��8�,���U8���`��P����U�|��U@���U`��U�7�U��i5�U��i5�U��x�m5�Um5���U1���������(������!���������������������������y���������U���������������U������������i5������UInput: UInput: ��X���U���(����U�um5�U`��U�7�U��i5�U��i5�U��x�m5�U�����������������������������������������������������������y���������������������������U���������������������������������������������U����������������������U����Ux���U�,���U0W�,���U�f��U`��U�7�U��i5�U��i5�U|<-- ```

Two questions:

  1. Is anyone still interested in the solution?
  2. Any insights about those Input logs, should they be fixed?
milutinke commented 1 year ago

@milutinke unfortunately Console.SetBufferSize will not work. This call will throw:

Unhandled Exception: System.PlatformNotSupportedException: Operation is not supported on this platform.

There is a similar issue reported for MacOS dotnet/runtime#27216

With this changes I was managed to get MinecraftClietn work in container (docker-compose + portainer) Diff

But I see another issue with logging PrintUserInput it looks broken (or it just log binary) here is snippet MinecraftClient output

Two questions:

1. Is anyone still interested in the solution?

2. Any insights about those Input logs, should they be fixed?

Yeah, I know, i've tried going down the rabbit hole, there is a problem after problem, I gave up on it. You can see my fork and maybe you will get some ideas.

CAMOBAP commented 1 year ago

Yeah, I know, i've tried going down the rabbit hole, there is a problem after problem, I gave up on it. You can see my fork and maybe you will get some ideas.

@milutinke Thanks for the response, but just to be on the same page, you also managed to fix the crash?

Right now I'm just trying understand why those suspicious logging statement Input: .... appears only in portainer, I don't see them when I run it locally with docker run -it ...

Maybe you have an idea about those Input: ....?

milutinke commented 1 year ago

Yeah, I know, i've tried going down the rabbit hole, there is a problem after problem, I gave up on it. You can see my fork and maybe you will get some ideas.

@milutinke Thanks for the response, but just to be on the same page, you also managed to fix the crash?

Right now I'm just trying understand why those suspicious logging statement Input: .... appears only in portainer, I don't see them when I run it locally with docker run -it ...

Maybe you have an idea about those Input: ....?

Yeah, we ran into the same issues. My diff: https://github.com/breadbyte/ConsoleInteractive/commit/8381eeb5ab11448f17f328cbf48b0cac91941a27

PS: Can't remember if I have done more than there is here, maybe i have but didn't commit, I do not remember.

breadbyte commented 1 year ago

Any insights about those Input logs, should they be fixed?

This output looks like it might be VT100 codes.

Turn these settings on in MCC, it might help.

[Main.Advanced]
EnableEmoji = false

[Console.General]
ConsoleColorMode = "legacy_4bit"

[Console.CommandSuggestion]
Use_Basic_Arrow = true
CAMOBAP commented 1 year ago

@breadbyte thanks for the support

Looks like ~Enable_Color = false~ Display_Input = false did the trick for me, but I don't really understand consequence of this config

From one of it I don't see anymore command which I type but I see suggestion "menu"

Anyway for my needs now it works perfectly thanks @breadbyte @milutinke

For the record: vt100_* codes works perfectly in portainer

UPD. it was Display_Input = false

milutinke commented 1 year ago

@breadbyte thanks for the support

Looks like Enable_Color = false did the trick for me, but I don't really understand consequence of this config

From one of it I don't see anymore command which I type but I see suggestion "menu"

Anyway for my needs now it works perfectly thanks @breadbyte @milutinke

For the record: vt100_* codes works perfectly in portainer

Awesome You can open a pull request, so others can use this in docker

CAMOBAP commented 1 year ago

@milutinke sure, sorry I misunderstood your response in https://github.com/breadbyte/ConsoleInteractive/issues/9#issuecomment-1731986729

I thought you resolved the crash and have only issues with strange Input... logs

Will prepare PR soon

breadbyte commented 1 year ago

If you can make a pull request with the changes, that would be great.

I've gained some motivation to continue working on MCC, so I'm planning to rewrite the entirety of the library (and hopefully migrate all the console legwork from MCC to this library, as it currently stands, MCC still does the majority of the color and vtcode work, and that should be thrown here instead) and this would be a good hotfix while I do that.

CAMOBAP commented 1 year ago

@breadbyte thanks you and all contributors for the hard work

Here is the PR #23, I'm not sure about the approach in general, but I can confirm that it works for me (tested more than 12h in a row, mostly for AFK)

breadbyte commented 1 year ago

Update was pushed to MCC https://github.com/MCCTeam/Minecraft-Console-Client/commit/911908bfaf79e52e5f0c586f03e903d5daf5d116