Well. It’s been… a few months, but here I am! Honestly I didn’t post for a while simply because I didn’t feel like it, I was a bit burned out. At one point I started writing one up, but never finished, so here I am starting a new one. But the past is in the past, and I’m ready for some more blogging! One quick thing before getting into the content. I did go ahead and make some changes to how I handle paragraphs, and I think it looks quite a bit nicer. Feedback, as always, is appreciated, but I hope you like the new look! Ok, today I’ll be talking about a tool I recently made for my personal use, and then getting right back into ReLife and a sneak peek into some stuff I’m considering working on in the future. Here we go again!

AFK Tool

Ok, so starting off today is part of the reason why I love coding. For those of you who don’t know, AFK stands for Away From Keyboard. Specifically, I’m refering to Minecraft where it mens you’re not actively playing the game, and your character is just standing there.

Some of my friends and I started a Minecraft server to play on, using the server hosting service called Exaroton. Their whole premise is that you “pay by the second”. Rather than paying for monthly uptime, the server automatically shuts down if no-one is online, and boots up when someone tries to join. The best part is that you only pay while it’s up.

Now in this server, I made an AFKable experience farm: essentially, I get XP by just standing there. I, because of course I did, wanted to be able to AFK there for as much time as possible. The catch? I couldn’t force the server to be on 24/7 because that would cost a bunch of extra money.

So originally my idea was that I would have Minecraft open in the background, and then have a script running so that whenever the server turns online it clicks on the join button, and then if I’m the only one online it would click on the exit button. Simple, right? Well… one quick revisal. I think it was partly because I wanted an extra challenge, partly because I wanted to learn more about how the Minecraft client worked internally, and partly, I thought that having Minecraft open in the background constantly would get very annoying, very fast. The revision? I was going to make it join the server without ever opening the Minecraft client. Get ready for a wild ride folks, because this quick mini-project soon turned into a multi-day adventure!

Ok maybe that was excessively dramatic, but it did feel a little daunting at the time. What I did to make it easier on myself, and this is crucial if you ever are trying to do a big project, was break it into chunks, work on them individually, then combine them into the finished project at the end. First chunk: join a Minecraft server without opening the client.

I think this was made a little easier due to the expertise I’ve gained from hours upon hours of delving into NMS (working with the Minecraft server source code). Essentially, the way Minecraft works is that the server and client send little bits of information called packets back and forth.

For example, when you try to move your character around, your client gives the server a move packet, and the server forwards that to every other player. It can get complicated rather quickly, however, and Mojang didn’t exactly leave a guide on how to replicate their work. That being said, they did leave behind a text file called a “mapping”.

Essentially, I can download the obfuscated source code, and then look at this file and it will tell me what the deobfuscated name of the class, method, field, etc. This is insanely helpful because there’s no chance I could decipher this code if everything were named “a”, “b”, “c”, etc.

Of course I also don’t want to have to go look that up every time I am trying to read some code, or import a class into my project. Thankfully, due to the wonders of freeware, I could do a quick Google search and find a tool someone else made that takes in a obfuscated file, a mapping file, and output the deobfuscated version.

Ok, ok, so now I have the (mostly, the tool wasn’t perfect) deobfuscated code. Now, along with the help of my IDE (IntelliJ Ultimate), I found the exact code that executes when you click the join button, and traced it all the way back into the dark nooks and crannies of its inner workings. Now this is going to make it sound really easy, trust me it wasn’t, but I essentially just copied the bits of code I needed. I made my program send the Minecraft server all the right authentication packets, and bam! I was in.

Alright, I’m going to back up a moment and talk about one more thing that was required for authentication, because it led me down a rabbit hole of many hours. Part of what you need for authentication is your Mojang authentication token. The way it gets that is that the launcher (which I didn’t have the code for) passes it in to the client when it launches it. I did some quick command prompt fanagling and got that, and put it into my code and it worked! Yay… until the next day. That was when I realized that the auth token changes, so I’d need to get it every time I ran the program in case it had changed.

Thankfully there is this wonderful wiki that’s been compiled, and it gave me the steps to retrieve that token. And then I realized it. Microsoft Secure Account (MSA). I’m sure many of you have heard of the huge Minecraft account migration. Essentially, Microsoft (who owns Mojang, the company who made Minecraft), decided to migrate everyone’s Minecraft (Mojang) account to use their Microsoft account. That means I have to go through Microsoft’s OAuth 2 authentication. You know this little popup, or something that looks like it?

Now that’s a screenshot of something my program generated, but when I first realized I would have to go through Microsoft I had no idea how I was going to do it. In fact, I was more daunted by that than logging on to Minecraft headless (without a window).

At first I tried to tell myself that I could just copy it from the Minecraft runtime arguments like that first time over and over, or I could just have my program launch Minecraft then automatically copy the arguments, or a dozen other bad ideas. But it was inevitable: I had to make the Mojang authentication work. Once I had set my sights on it, it was all but assured I was going to make it happen.

I’m not going to go super in-depth on how it works, but I’ll give you the basics, and of course if you wants to know how to do something like this yourself feel free to contact me.

Ok, so essentially what I did was copy someone else’s code. Alright, alright, I know that doesn’t sound very good, but I promise I did have to put some effort in. I couldn’t find any code that did what I wanted in Java (the language I’m using), so I had to transcribe a JavaScript script from GitHub into Java. Essentially what it’s doing is opening a browser to the Microsoft login webpge, and and telling it to give me the first of the auth tokens as a URL parameter (the things after the “?” at the end of a URL). Then it passes that token to another website, retrieves some token or other, and does that like 5 more times. I have no idea how the creator of the script figured out all of these websites, but if you’re curious here’s the list in order:

https://login.live.com/oauth20_authorize.srf redirects to https://login.live.com/oauth20_desktop.srf which has the token in the URL parameters, then it makes a FETCH request to https://login.live.com/oauth20_token.srf which returns an access token, which gets passed into https://user.auth.xboxlive.com/user/authenticate which returns a token and user hash, of which the token gets passed into https://xsts.auth.xboxlive.com/xsts/authorize which returns another token, and then that token and the user hash from earlier are sent to https://api.minecraftservices.com/authentication/login_with_xbox, which finally returns your Minecraft access token.

So yeah, I didn’t figure that out on my own, but open source software to the rescue. A few days of development went into transcribing that into Java, but I eventually figured it out, and let me tell you, the rush of dopamine when it finally made that window pop up and get the access token was euphoric: another reason I love programming. You sort of get that in other fields as well, but with coding you generally have to debug a lot, and slowly but surely make progres towards the end goal, so when that goal finally arrives it feels amazing.

Anyway, finally two out of the three chunks have fallen into place: the last remaining thing is to make it integrate with Exaroton. This was probably the easiest part, but came with its own challenges. It’s the easiest because Exaroton made this amazing API, which supports Java. The biggest challenge was that part of that API… didn’t work.

What really sucked about it is that errors in an API you’re using are the hardest type to debug because you don’t know that code. If the bug is in your own code, you wrote it so you already have an idea of where it might be. If something isn’t working deep within the API, like in this case, it’s really hard to find the issue. On top of all that, this issue was made even harder to find, because it ended up being an issue with their backend - nothing I could do on my side could fix it.

Now this is not to slander Exaroton, they handled it wonderfully. I just got on their Discord server and asked the developer of the API about it, and within 24 hours the issue was fixed.

Essentially what the Exaroton part does is it tells their backend to notify me every time the “state” of the server changes: every time it goes online, offline, or a player joins or leaves. Then what I do is every time I receive a status update, if the server is online, I check the player count. If someone is online and I’m not connected, it connects me. If there’s only 1 player online, and I am connected, I disconnect because that means I’m the only player online and I don’t want to keep the server online.

And that’s almost it! The final thing I needed to do was make a custom packet handler (remember, packets are those little bit of data that let the server and client synchronize). Essentially, since I’m running a bare bones client I ignore most of the packets. I don’t care if some entity moves because I’m not rendering the entity at all. I don’t care if some block is broken because there’s no player watching to care about that block. The only packets I need to send to the server are the occasional “keep alive” packet, that lets it know I haven’t timed out, I’m still there.

There! Now, it’s done. Finally, here’s another of the 3 main reasons I love coding: the flexability. As a simple player who doesn’t know better, they may just manually open Minecraft every time someone else is online to AFK. But to me, a programmer, I simply… created a new tool. For all the GUIs and interfaces Windows provides, none of them can do what I wanted, so I simply made it myself.

And the most beautiful part to me? I didn’t have any experience with anything but the Java language going into this. I didn’t know how to interface with Exaroton, I had absolutely no idea how to log into Minecraft without even opening the window, and I certainly didn’t konw what the hell I was doing, still don’t really, with the Microsoft authentication. And I learned all this with but two things: my brain, and Google.

Alright PSA aside, let’s hop into… zombies!!

Braaaaaiiiinnnnsss

I’ve got two things to talk about with zombies, both of which stemmed from one of my friends approaching me with a Minecraft mod idea. Essentially, in Minecraft one of the monsters is the zombie. The premise of this mod is that instead of just the base zombie walking at you and swinging its arms, there would be many different types of zombies. For example there could be one that can smash through blocks, one that can run fast, etc.

I love this idea, and I love the fact that someone approached me with this, so I’ll likely be working on it at some point over the summer. For now, though, I’m going to talk about the other thing that stemmed from that idea.

In ReLife, I really wasn’t feeling any motivation to work on it, so I decided to come up with a new zone. New things are always fun and interesting at the beginning, so I figured if anything could kickstart development again it would be coming up with a creative new zone.

Since literally earlier that day I was told the mod idea, my mind immediately went to zombies. I’m imagining swarms of zombies following the players but… that’s not enough. On top of that, there are going to be many different types of zombies.

With that in mind, I got to brainstorming. I ended up with 7 different types: Basic, Sharpshooter, Pyromaniac, Berserker, Shielded, Necromancer, and Miner. I haven’t gotten too far into development yet, but I’m super excited: which is just what I was hoping for. For now I’ll just give you a brief run-down of the ones I’ve created thus far (skipping basic, that’s just a normal zombie), and will explain the others in the coming posts (Yes, I’m planning to get back on a weekly schedule!).


Sharpshooter

This zombie will be holding a crossbow: similar to a pillager if you know what that is. The main issue this is hard to code, and still a little buggy, is that a zombie isn’t designed for holding a crossbow. The way mobs work in Minecraft is that they have “goals”. To get this to work, I have to remove the melee attack goal, and give it a crossbow attack goal. Again, a little finicky, but it works.


Berserker

Pretty simple, this zombie is a glass cannon. It has higher damage, higher speed, low health, dangerous if you leave it be but pretty easy to get rid of.


Shielded

This should be pretty simple, but, unfortunately, it was not. The way shields work in Minecraft is that while you’re using it, any attack from the front is blocked, but if someone hits you with an axe, they can disable your shield for a little bit so that you’re open to other attacks. The idea for the shielded is that you can’t damage them unless you first disable their shield with an axe, or while they’re attacking you their shield will be down briefly. Unfortunately, the way the Minecraft code is written, it only checks to disable a shield for players, but adding in those checks wasn’t too hard. A short amount of debugging later and it’s working.

Wrapup

And that’s it! My first post in 5 months, complete. Of course if you have any suggestions please contact me, and I hope you enjoyed reading it as much as I did writing it. If you did enjoy, and know someone else who you think would as well, it would be cool if you could refer them here! As I said earlier, I’m hoping to get on a weekly schedule again, and I’m super excited to be working on my various projects over summer break. See you all next time!