#Console Logging Encoding Problems

1 messages · Page 1 of 1 (latest)

dark quest
#
package me.lianecx.smpplugin;

import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;

public class ConsoleLogger extends AbstractAppender {
    private boolean isLogging;
    private List<String> loggedData;

    public ConsoleLogger() {
        super("SMP-Plugin", null, null, true);

        isLogging = false;
        loggedData = new ArrayList<>();
    }

    public void startLogging() {
        isLogging = true;
    }

    public void stopLogging() {
        isLogging = false;
    }

    public void clearData() {
        loggedData.clear();
    }

    public List<String> getData() {
        return new ArrayList<>(loggedData);
    }

    public void log(String message) {
        if (isLogging) {
            loggedData.add(message);
        }
    }

    @Override
    public boolean isStarted() {
        return true;
    }

    @Override
    public void append(LogEvent event) {
        log(event.getMessage().getFormattedMessage());
    }
}
solar salmon
#

can you throw that in a paste?

#

?paste

dark quest
#

probably doesnt work in threads

#

@tawny bison

#

?paste

solar salmon
dark quest
#

I also tried this as the constructor ```java
super("SMP-Plugin", null, PatternLayout.newBuilder().withCharset(StandardCharsets.UTF_8).build(), true);

#

Didnt really change anything

solar salmon
#

Test if its teh formatting that is breaking it. In append use event.getMessage().toString() to see what the base string is

dark quest
#

And again, still logging correctly

solar salmon
#

ok, lets try and fix a few things. You shoudl move off a deprecated constructor java super("SMP-Plugin", null, PatternLayout.newBuilder().withCharset(StandardCharsets.UTF_8).build(), true, Property.EMPTY_ARRAY);

dark quest
#

note that im using api version 1.13 and java 8

dark quest
#

there are a lot of imports avaIlable

solar salmon
#

no clue

dark quest
#

this should be the correct one

#

but theres no EMPTY ARRAY property on it

dark quest
#

and how do you know its deprecated

solar salmon
#

the constructor you are using says deprecated

#

atleast in my IDE for 1.18.2

dark quest
#

theres only these 2 overwrites

dark quest
solar salmon
#

does your 1.13 have the log4j exploit fix?

#

it was fixed in Spigot but probably not in paper

dark quest
#

what was fixed?

#

Im not using the paper api

#

im using a paper server though

solar salmon
#

it was a remote code execution exploit in log4j

#

there is a startup switch to preven tit... one sec

#

-Dlog4j2.formatMsgNoLookups=true

dark quest
#

that was definitely fixed in paper as well

#

But youre going offtopic arent you?

solar salmon
#

yep

#

ok lets test, in your appender try java String msg = String.format(Locale.ENGLISH, event.getMessage().getFormattedMessage(), (Object) getPropertyArray()); log(msg);

#

That way we can see of the encoding is wrong going in

#

see what msg is after formatting

dark quest
#

getPropertyArray()?

solar salmon
#

just fetches the array that the appended was setup with

dark quest
#

well i dont have that method

#

where are you getting it from?

solar salmon
#

does it not exist for yiou?

dark quest
#

nope

solar salmon
#

then use Property.EMPTY_ARRAY

dark quest
#

i dont have that either

solar salmon
#

oh

#

it should be a Property[]

dark quest
#

i can just leave it out

solar salmon
#

k

dark quest
#

if its empty

#

well it still shows the same thing

#

Btw, maybe we can change the whole fundamental idea

#

What im ultimately trying to do is just receive the response of a command which im executing through the plugin

#

This is unfortunately very hard to do and ive tried some things but the best working one was using the logger which starts logging before i execute the command and immediately stops after

#

Maybe theres an easier way of doing this

#

It would solve this problem and be overall probably cleaner

solar salmon
#

I can't see that log4j would be trying to alter teh encoding at all. There has to somethign funky with how the string is getting to the logger

dark quest
#

hmm

dark quest
solar salmon
#

Not really. The command system isn;t designed to get anything more informative than a yes/no

#

I'll assume you are sending commands to other plugins

dark quest
#

?

#

wdym

solar salmon
#

via dispatchCommand?

dark quest
#

yea

solar salmon
#

is there a reason you can;t use the plugins api?

dark quest
#

i read theres a way of overriding the sendMessage method of a command sender but that didnt really work for me

dark quest
#

im executing vanilla commands

solar salmon
#

ah

#

relying on the logger for that is going to be unreliable as it starts out async

dark quest
solar salmon
#

probably not

#

where are you displaying the messages that you see the wrong encoding? If as you say they are correct in console and log

dark quest
#

in my second app

#

in the console of my second app

#

where im sending the messages to

solar salmon
#

in which case it seems the method you are using to send the string across is wrong

#

or that console is not UTF-8

dark quest
#

oof

#

maybe

#

How could i find out

#

its a js app and i tried this

    console.log(Buffer.from(respMessage, 'utf-8').toString())
#

which shouild just convert it to utf8

solar salmon
#

I don;t do js so not clue

#

its been years for me since I touched js

#

Node

dark quest
#

do you have any pseudo-code?

solar salmon
#

how are you sending to js?

dark quest
#

http response

solar salmon
#

can you read teh encoding on the response?

#

it should be in teh header info

dark quest
#

probably

#

its not really in there

#

i can specify the header though

solar salmon
#

you can also before sending ensure it is UTF-8 by string.getBytes(StandardCharsets.UTF_8)

#

include the encoding in teh header and Node should handle it

dark quest
#

okay i need a break 😅

#

Ill come back tomorrow

#

its not setting the header for some reason

solar salmon
#

ok

dark quest
# solar salmon ok

Btw i almost forgot. Another hint that the logger is outputting wrongly encoded strings is that the stripColor method couldnt remove the comor coded and we had to make our own one with the special regex

solar salmon
#

thats true

dark quest
#

And the regex is checking for \x7f

solar salmon
#

instead of hooking into log4j perhaps you shoudl hook the console

#

This would give you what is actually being pushed to the console

dark quest
#

Id have to remove the prefixed though

#

Like the time and the sender

dark quest
#

Btw, i just wanted to thank you for your help. This really means a lot :D

dark quest
solar salmon
#

info

dark quest
#

all responses?

#

the error ones too?

solar salmon
#

question. the string from yesterday with the 7F at the front. was that the string whilst IN the logger, or after you sent it across to your app?

dark quest
#

The \x7f was in the second app

#

Because log4j displayed it correctly

solar salmon
#

in that case, there is nothing wrong with your logger

dark quest
#

in the minecraft console

solar salmon
#

the issue is purely in how you are sending it to the app

dark quest
#

it isnt

#

I think

#

i do not think its the transfer

solar salmon
#

I do.

dark quest
#

Then why does this regex work and the stripColor one doesnt?

\x7F([(\da-fA-F)])
solar salmon
#

is that regex done in your MC plugin code or on your app?

dark quest
#

thats the bukkit regex

dark quest
#

\u00A7

#

it uses the unicode char

solar salmon
#

ok

dark quest
#

and ours work

#

[0-9A-FK-OR]
btw this is correct

#

we didnt include the reset (r), underlined (l), bold etc

solar salmon
#

K-OR?

#

ah

#

we shouldn;t have to

dark quest
#

?

solar salmon
#

ah no ignore me

#

I was just thinking of the 16

dark quest
#

ohh

#

and it does (?i) for ignoring case?

#

yea

solar salmon
#

yes it needs /i

dark quest
#
(?i)\x7F[\dA-FK-OR]
#

this is our final regex

solar salmon
#

did you try with the console logger to see what you get there?

dark quest
#

im trying rn

solar salmon
#

k

dark quest
#

thats why i wanted to know the level

#

is it always INFO?

#

also for syntax exceptions

#

like when it says

#

An entity is required blabla

#

or

solar salmon
#

I'd not be suprised if it was a log4j issue. That thing is a bitch to work with

dark quest
#

awdawd....<------HERE

#

ill just try always info

solar salmon
#

you could use .ALL

#

pretty sure there is an ALL level

#

well for now you can ignore the level. we just need the message

#
plugin#getLogger().setUseParentHandler(false);
Plugin#getLogger().addHandler(new LogHandler());```
solar salmon
#

that attaches the LogHnadler to teh logger

dark quest
#

so its not a global logger?

solar salmon
#

you add it to the plugins logger

#

or bukkit logger

dark quest
#

but that logger doesnt actually log

dark quest
#

well um

#

it threw a bunch of errors

#

stackoverflow

#
public class ConsoleLogger extends ConsoleHandler {
    private boolean isLogging;
    private final List<String> loggedData;

    public ConsoleLogger() {
        isLogging = false;
        loggedData = new ArrayList<>();
    }

    public void startLogging() {
        isLogging = true;
    }

    public void stopLogging() {
        isLogging = false;
    }

    public void clearData() {
        loggedData.clear();
    }

    public List<String> getData() {
        return new ArrayList<>(loggedData);
    }

    public void log(String message) {
        if (isLogging) {
            loggedData.add(message);
        }
    }
    @Override
    public void publish(LogRecord record) {
        System.out.println(record.getLevel().getName());
/*        if (record.getLevel() == Level.INFO) {
            log(record.getMessage());
        }*/
        log(record.getMessage());
    }
}
#

i think i cant sysout in the publish method

solar salmon
#

you can

dark quest
#

well its at that line

#

at the sysout line

#

ohh

solar salmon
#

ah paper, it hates sysout

dark quest
#

yea

#

thats what i said

#

ill download the new version real quickj

#

and i also removed the sysout

#

no errors now

dark quest
#

It doesnt seem to work

solar salmon
#

gets nothing?

dark quest
#

yeah

#

data is emptz

solar salmon
#

odd. I know it works at teh plugin level. I've not used it on the Bukkit logger

#

but it should. identical loggers

#

try leaving out the setParentHandlers

#

allow all handlers to parse the messages

dark quest
#

it looks like its just the plugin logger

solar salmon
#

ah thats a bummer then

dark quest
#

\

#

this maybe?

#

add the handler to this one

solar salmon
#

or use getLogger passing the Main class of Spigot/paper

dark quest
#

?

#

wdym

solar salmon
#

From Spigot Main class Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);

#

logger being java.util.logging.Logger;

dark quest
#

whats main

#

Main.class

solar salmon
#

yes, Spigots Main.class

dark quest
#

i dont have Main

solar salmon
#

its called Main as its an executable

dark quest
#

where does it come from

solar salmon
#

ah you'd need NMS

dark quest
solar salmon
#

org.bukkit.craftbukkit.Main

dark quest
#

this doesnt work?

solar salmon
#

nope

dark quest
#

hmm

#

getServer.getLogger also didnt work

solar salmon
#

how about Logger.getLogger("Minecraft");

dark quest
#

how do you know the name is Minecaft?

dark quest
#

?

#

ah

#

still nothing

#

setUseHandlers(false)?

solar salmon
#

leave that line out

dark quest
#

i did

solar salmon
#

thats for overriding current handlers to only use ours

dark quest
#

should i enabel it?

solar salmon
#

default is enabled

dark quest
#

i mean disable

solar salmon
#

nope

dark quest
#

okay

#

then it doesnt work

solar salmon
#

probably not 🙂

dark quest
#

I didnt disable it

#

And it didnt work

solar salmon
#

I'm at a loss then

dark quest
#

So this is the end result...

#

ig i dont have any other idea too

#

ill just use the old logger

#

the log4j appender

solar salmon
#

I guess you have no other choice

dark quest
#

I mean we did manage to fix the color codes

#

its just the other unicode chars

solar salmon
#

other unicodes are unchanged so they have to be transmitting incorrectly

#

somethign between you storing the string and getting it to your app

dark quest
#

what?

#

This wouldnt make sense

#

if the § is encoded weirdly then so are all the other non-english chars

#

its not a transmission problem

dark quest
solar salmon
#

I've no idea how its messing up the color code, but I don;t think its unicode related

#

if its not related to the encoding then the other characters should be fine

#

if it is the encoding then ALL unicodes will be broken

dark quest
#

Anyways, thank you for your amazing help and effort :D

#

Ive reached my main goal which is removing the color codes