Send "MOTD" to Minecraft client from custom Netty server - java

I have a basic Netty server (From the tutorial) (http://netty.io/wiki/user-guide-for-4.x.html), and it recieves the requests from the client, but how would I go about sending a string to the client?
For example, on a normal Minecraft server, you specify the "MOTD" in the configuration file, and when a client pings it from the server list, it will display that string. I need to do the same thing, but from my server code.

If you wish to send the MoTD to the client you will have to figure out what gets sent in terms of protocol and data.
For example in the most basic form the data sent could be 1 byte for action (display motd) and then variable length for a string.
If I had to find out how to send this I would go look at the open-source bukkit repositories or the Minecraft Decompiled Code Repository to find out the way to do it myself.
Update:
Upon looking at the code it seems that also Minecraft uses Netty, so this plays in your advantage in terms of understanding it. Unfortunately the code is unofficially decompiled and thus obfuscated.
Update 2:
I believe the class you should inspect is
net.minecraft.server.PacketStatusOutServerInfo
and the data sent appears to be JSON generated by the ServerPing class.
You can also check out Minecraft Protocol (specifically Ping); a place where modders can find an explanation of protocol & encryption.

This handler shows the sending of the MOTD:
https://github.com/Bukkit/mc-dev/blob/c1627dc9cc7505581993eb0fa15597cb36e94244/net/minecraft/server/LegacyPingHandler.java
It just happens to be that the MOTD handling goes on line number 69: https://github.com/Bukkit/mc-dev/blob/c1627dc9cc7505581993eb0fa15597cb36e94244/net/minecraft/server/LegacyPingHandler.java/#L69
When the channel receives the ping packet, it encodes the response into a ByteBuf and writes it back out of the channel.
Note that there are a few decompilation errors on the file - ignore them and fix it.

Related

2 Same HTTP Requests Give Different Results?

What differentiate these 2 requests that cause them to have different results/responses from the server although they should be the same ?
Request initiated by Chrome after a simple
click/navigation(successful, response code is 302)
I simply copied
that request as a curl and imported it to Postman and then postman
hanged
I did the same with Java - HttpUrlConnection(mimicking all the request headers and cookies like Chrome sent), but it hanged and waited forever. Is this simply because of the server logic that doesn't accept non-browser client ?
Here are the steps that I tried:
1. Visited this link: https://www.tokopedia.com/p/handphone-tablet/handphone
2. I opened the inspector and opened the Network - All tab
3. I clicked one of the products
4. I clicked the top request from the Network - All tab
5. I copied it as cURL bash
6. I imported it to Postman
7. I ran that request
8. Postman hanged
Actually the problem might even go deeper than what the other answers say.
So neither the User-Agent request header nor telnet might solve that problem (unless you initialize the TLS handshake also with telnet MANUALLY, but that is near impossible to complete).
TLS fingerprinting
If the connection is an SSL/TLS connection, the server could detect which algorithm is used to generate keys, and most applications have their specific signature / cipher.
So only by the TLS handshake alone you can tell Chrome from Postman or FireFox or Java. Java usually - unless a JVM implementation REALLY wants to go off-road - has the same signature across all platforms, using the same cipher/algorithm across all implementations.
I am sorry I cannot properly recall the name of this technique. The first project I know that published this is called something like "A3" or "S3". Salesforce published an article about JA3 analysis. They describe the technique and show a list of signatures and applications so you can guesstimate what app you're talking to, without the need to even decrypt the data: https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
My Solution
I had that same problem too, wanted to scan the NVidia or AMD servers for graphics card availability. Did not work from Java, so after a lot of research, finding the project mentioned above, I simply used Selenium to control FireFox and that got the proper server responses and I achieved my goal this way.
The only way to be sure that the exact same data is sent is to manually send it yourself through something like telnet. I had a similar problem once- it turned out that the browser was sending the data in one big chunk, while my code was sending it line-by-line. No site should have this problem, but it's possible that it exists.
The server might be checking for User-Agent request header and will block traffic that does not originate from a browser. Try setting the header in curl or your Java Code to a value corresponding to (any) browser. I've encountered such behavior on some e-shops and commercial websites.

NServiceBus and Java integration

We have several microservices, most of them written in C#, but one written in Java. We're using NServiceBus and RabbitMQ for communication between the .NET services. We have one case where one of the C# Components needs to talk to the Java component with a Request/Reply over RabbitMQ.
When using NServiceBus the reply Queue is labeled with AnyQueueName-1 where the -1 indicates that this is a Reply Queue.
Debugging the Java service, I can see that I'm able to send Messages from the C# Service to the Java service. Once the Java component is finished processing the Message, it's supposed to send back a Message. Here is where all the problems starts.
I can see that it's supposed to send the Message to the correct Queue. The name has been verified within the RabbitMQ Management Tool. But there is not activitiy in this Queue.
No exceptions are thrown on the Java side, which to me sounds like its able to send the message, but where does it go? I do not expect that NServiceBus and Java will work together perfectly, but at least I should see some activity in my expected queue.
The relevant Java-code looks like this:
Message responseMessage = rabbitTemplate.getMessageConverter().toMessage(response, responseProperties);
String replyTo = requestProperties.getReplyTo();
rabbitTemplate.convertAndSend(replyTo, responseMessage, cd);
Where the variable replyTo is the name of the queue that I expect the message to be pushed to.
Can anyone give me a push in the correct direction? Where should I debug next?
Thanks!
This issue is hard to identify without actuall access to the infrastructure.
It seems to me, considering that your Java client successfully publishes to the RabbitMQ broker, but the C# client doesn't react to the messages, that your message serialisation might be missing something.
A few things that you should check:
Take a look at the native integration with RabbitMQ sample
The NServiceBus documentation has a section on how to use native RabbitMQ integration.
You can download the sample and see how the particular guys got it to work.
NServiceBus uses specific header attributes within messages.
One lf these is the NServiceBus.EnclosedMessageTypes, which alows NServiceBus to identify the message type, more specifically to map it to the corresponding C# class implementing IMessage. Also the NServiceBus.MessageIntent header would be needed.
I suggest you check the NServiceBus Message Headers documentation, in your case specially the Reply Headers section. Make sure you add the NServiceBus required headers from your Java client as explained in the RabbitMQ API-Guide. I can't tell which of those headers are mandatory for NServiceBus to work, so trial and error is your friend.
Track Messages published by NServiceBus in RabbitMQ
Compare the messages published using NServiceBus with the ones you publish using your Java client. Here is a link for one possible solution on how to trace RabbitMQ messages and their payload. This way you might identify differences between the two message types and their content.
Use NServiceBus ServiceControl
One of the advantages of NServiceBus is the tools it brings with it. Set up an instance of ServiceControl and use the ServiceInsights to check messages and errors per endpoints. You might find your Java messages listened.
Generally this tooling is great for production environments and I can only recommend it.
If nothing gets it to work, another option for you would be to create a slim REST API in C#, as a publisher gateway, that would take the POST requests and publish the content using NServiceBus to your RabbitMQ. You would be able to reference your project containing your messages and use them as your models for the API.
A possible example:
POST https://busgateway.corporate.com/api/{endpoint}/send/{messagetype}
body:
{
"property": "value",
"publisher": "java client"
}
That way your Java client would send messages using http requests.

Starting my first android app. How can I easily test if the server has received a message?

I am experienced with Java and have some experience with PHP (the server scripting language I will be using unless anybody tells me I shouldn't for some reason. I want to just send a string via POST to the server. Because there is not actually a webpage being created, I can't just echo the string if it is received. How should I test if the string was received by the server?
Edit:
After further research, it seems like echo doesn't just print to a browser, it sends a string through the http connection to whatever is connected to the php page. I should then be able to echo a response and receive it through an input string on the Java end. Is this correct?
You could use echo, as you mentioned, but the more common and reusable method of debugging PHP as you progress is the use of error_log(). You can view its output on the PHP server in the php.log file, commonly found at /tmp/php.log.
You can watch this file in real-time via the Unix command tail -f /tmp/php.log.
Further, you can output various forms of data by calling it with print_r() like error_log(print_r($data, TRUE));.
I believe you should be properly sending back Responde codes in your php scripts.
Please check: How to send a status code in PHP and Android: How get the status-code of an HttpClient request.

JavaMail - Stop automatically sending read receipts

I'm developing a Mail Client (IMAP/SMTP) with JavaMail. This client talk to an Exchange 2010 Server that automatically sends read receipts when I set the flag SEEN in messages that require them. How can I avoid the server to send these receipts? I tried to remove the Disposition-Notification-To header from messages but i get the following exception:
javax.mail.IllegalWriteException: "IMAPMessage is read-only"
even if i open their folder in READ_WRITE mode. I read that this problem is due to an IMAP protocol limitation. Is there a way to not send read receipts?
You can't do that in your client. Your client doesn't do it, and IMAP offers no way to configure Exchange.
(Also, IMAP offers no way to modify messages. Once stored, a message can be cached forever by any client and not be modified by any other client.)
The right thing to do is to reconfigure the server.
Lacking that, you could make a copy of the message, modify the copy to remove the header, append the copy to the original folder, and delete the original. You'll need to use the IMAPMessage.setPeek method to prevent the SEEN flag from being set on the original message. Use the MimeMessage copy constructor to make the copy. Note that this will be expensive if the message is large.

client server communication solution

I'd like to ask if my solution is OK or if there is a better way to do this.
I have an Android client and a Tomcat server. I send a few words (as a POST saved in JSON) to server and server sends me back a JSON with an article containing those words.
Suppose it's a public app, so a lot of people may send a 'request' for an article.
I'm not sure if I'm doing this right, or if there's another and proper way to do this.
Thanks
Since you android client appears to be "Getting" an article you might consider using a GET request as opposed to a POST request, however the differences are trivial. Otherwise your solution sounds perfectly fine. Look into "REST" and "SOAP" as different options for writing web service APIs.

Categories