TerminalConsoleAppender icon indicating copy to clipboard operation
TerminalConsoleAppender copied to clipboard

Deprecation of MinecraftFormattingConverter

Open stephan-gh opened this issue 4 years ago • 5 comments

TerminalConsoleAppender was never meant to be Minecraft-specific. It works just fine for other uses as well. The only Minecraft-specific code that it contains is the MinecraftFormattingConverter that is used to translate legacy color codes (§c etc) to ANSI color codes. I put that here because that was convenient back then when I needed the same code on multiple platforms.

But now legacy formatting codes have been deprecated for a long time, and there is no standard representation of newer features like RGB colors anymore. At this point, it seems easier if the projects that need it (and perhaps even want modern features like RGB support) make a copy of MinecraftFormattingConverter and change it to their needs. For example, Paper has made such a copy in https://github.com/PaperMC/Paper/pull/5205.

As additional inspiration in case someone wants to implement this properly I will briefly describe a completely other, but potentially much cleaner approach that avoids legacy color codes entirely. I never found time to implement it, but I think it should work.

In particular, Log4j2 has the Message interface that can be passed to all log calls instead of a raw String. The idea would be to implement a custom Message class to retain all the properties of a text component (colors, hover events, ...), without having to serialize it into a raw string. Instead of logger.info(component.toLegacy()) you might use logger.info(new ComponentMessage(component)). Then there is a sub-interface called MultiformatMessage, which can render itself differently based on the output it is appended to. So instead of having to strip color codes to log to a file, we can avoid generating them in the first place!

Something like this could be implemented once for a chat component API like adventure and then shared between projects that make use of adventure.

@zml2008 I believe we discussed this at some point? Did you ever finish implementing it? (I hope it was you, can't remember exactly and also can't find the chat log anymore. :D)

stephan-gh avatar May 07 '21 19:05 stephan-gh

minecrell is alive! 😱

Keep tryna reply to this but I can't quite convey what I wanna say all too well,

Basically, I can understand wanting to get rid of the MC specific stuff, especially when we have divergence with stuff like spigots weird format, ontop of the fact that other platforms generally don't really have any representation of the chat outside of a legacy format we're all tryna convince people to get away from, especially as it's missing a good chunk of the feature set people have come to love

I think having a logger which can deal with adventure would be great, for one, it's adventure, for two, as much as it's tied to MC, it's doesn't seem unusable outside of MC, at least for a lot of typical stuff like text formatting, which is a horror when tryna deal with ansi outside, i'd much prefer to leave that mess to somebody who's not me rather than having to determine in my own apps if ansi is available, what features I can use, etc

electronicboy avatar May 08 '21 19:05 electronicboy

I think having a logger which can deal with adventure would be great, for one, it's adventure, for two, as much as it's tied to MC, it's doesn't seem unusable outside of MC, at least for a lot of typical stuff like text formatting, which is a horror when tryna deal with ansi outside, i'd much prefer to leave that mess to somebody who's not me rather than having to determine in my own apps if ansi is available, what features I can use, etc

There is no need to put that code into TerminalConsoleAppender. It could just become some part of Kyori/Adventure I guess and then you can depend on it additionally. Log4j is quite extensible there.

stephan-gh avatar May 08 '21 19:05 stephan-gh

Yea, I was somewhat for adventure support in TCA given that it would be a nice base, but, now that you mention it, it being done over in the adventure side of stuff itself seems a lot more ideal.

imho, having a text format capable of representing colors and formatting and such without having to dig into ansi and determining support, etc, does sound like a cool wider goal, it would just be somewhat weird given that adventure is designed for an environment that supports much more

electronicboy avatar May 08 '21 19:05 electronicboy

I've done some work on this, but haven't had a chance to finish implementing it. There are some pieces out there so far:

  • Sponge has handling to allow logging components directly: https://github.com/SpongePowered/Sponge/blob/98eac411982fbeaac1d5019c3151f502053dfcf1/vanilla/src/main/java/org/spongepowered/vanilla/chat/ReusableComponentMessageFactory.java#L134 (I've sent an earlier version of this to Minecrell I believe) -- there is a bit of complexity there just to handle log4j being used both inside ModLauncher's TransformingClassLoader and outside that loader, but a stripped down version could be provided. Unfortunately the MultiformatMessage doesn't work super well with garbage-free logging, so that implementation may change once I get to fully implementing ANSI support in Sponge, to just create a new Message instance if the provided Object parameter is a Component.
  • I have a WIP formatter that is not attached to any particular component implementation (so it could be used on adventure, or native MC chat components, or whatever else): https://github.com/KyoriPowered/ansi/blob/trunk/src/main/java/net/kyori/ansi/ANSIComponentRenderer.java
  • A third component would go into Adventure that provides glue between the Adventure components and the ansi formatter library, based off @Narimm's PR

zml2008 avatar May 08 '21 19:05 zml2008

Just an update on this front -- Mojang has been moving Minecraft to use SLF4J for its logging API, so logging components directly is a bit more complicated. The approach I've chosen with Adventure is to implement a Logger wrapper that overloads every log method to accept a Component parameter (see https://github.com/KyoriPowered/adventure/pull/757). This approach could be applied similarly to create wrappers accepting Minecraft's components directly, or any other implementation.

Unfortunately not much progress on the other elements of the strategy, but this at least shifts those to an implementation detail, so the end-user API can remain consistent while the way components are converted into ansi control sequences is evolved over time.

zml2008 avatar Apr 26 '22 04:04 zml2008