My very cool projects

Go back

Discord Lite

I've done it again. Another project that involves Discord that I didn't have to touch. Oh well, I've tried and I've miserably failed. Though, I'd like to still share this project here :)

But why

The first thing I want to get out of the way is the reason why I started touching Discord again. You see, me and Discord go back a long way and I've been a vivid user of it for a LOONG time. This also involves me wanting to test the boundaries of what I may (or may not) do on Discord. This might've gotten me banned multiple times already.

ANYWAY, you wanted to know why. "Why???" you ask? Well, I've got a friend. A really good friend of mine. We like to play Valorant together. Though, he has to call me on Discord through his phone. "Why?" (yet again,, you ask). Because his laptop can't run Valorant and Discord at the same time.

The root of the problem

We'd like to know what's causing all this. You see, my friend originated from teamspeak, a very basic voice chatting application (which is nothing compared to Discord).
- Not a Discord fanboy btw

The problem here is that the Discord application is a whole browser at itself. Everyone knows it, it helps with maintainability on Discords side, but basically fucks anyone over that doesn't have at least a mid rage pc for gaming (sorry for the language). So, while you're running Discord you would run a browser in the background at the same time. At this point you might as well just open your browser and use Discord there, and enjoy all the other features of a browser while doing so.

Just funny haha meme of what if we were to have an app that loads in other apps (also called a browser)

TECH STACK CHOICE

The most interesting question ofcourse. WHAT DID I USE TO TRY TO FIX THIS???

c#

Yes, the product by Microsoft

But Aaron, WHY?

I didn't want to go too deep into a low coding language for this. c# is high asf. Next to that c# has LINQ. Tldr; LINQ is SQL on steroids to use within c# code.

On a more serious note, I also kind of hoped to make it cross-platform which horrendously failed.

To make it cross-platform though I used Avalonia. Why Avalonia you might ask? Idk,, they promise good things on their website, and the website makes a good impression in general.
Also, before choosing for Avalonia I scrolled through their documentation, and it's nicely documented! OH and almost forgot to mention MVVM here. Yes, that also

First step!

The first step imo was to check out if I had the skill to remake the Discord styles within Avalonia. Don't take me wrong, theoretically you should be able to recreate anything that's made in a browser in C# code as well (with Avalonia), I spent a horrifying 15 minutes to get this result: to eventually end up with a login page that looked exactly as the Discord login page.

Why I striped the previous thing through you may ask? I thought I had a screenshot of it, but apparently don't, which is very disappointing of myself. Instead, take this random picture of me taking a break:

11 hours of Albion wooohoooo

Anyway, I've concluded that recreating the styles of Discord within Avalonia is easy. And 100% doable.

The worst step! (2nd step btw)

Now that we have a login page ready to go and all. We should login. When we're logged in we basically get access to all the API endpoints accessible to users normally. So this is the MOST CRUCIAL step.

Login using email & password

This would be the most user-friendly way to do it. It would allow users to just login as normally in a Discord application. After creating the viewmodel and model for the view, I was ready to make the API call to login. And that's where it all went wrong. Discord has CAPTCHAS. I, personally, hate captchas.

Solution 1: Webview

The first solution I thought about was using a webview. Yes, it's a dumb ass solution especially since the whole reason I started this project was to not use a webbrowser within an app. I still thought that the webview would only be used for loading in captchas, and then be destroyed again. Meaning that the webview would only start consuming processing power when the user was actually doing tasks in the app. Which then made it an acceptable solution.

You know what wasn't easy though? FINDING A WEBVIEW. There are multiple webview solutions available online, but none that natively supports Windows, linux AND osx on the same time. Some webview solutions only did windows, some only did linux there was none that did it all. "Am I really going to create a webview control for this stuff?" went through my mind. My laziness took over again. Here's another (random) picture of me taking a break:

ANOTHER 9 HOURS OF ALBION???

(not really a) Solution 2: Reverse engineer captcha

I've done this before. Yes. I once got so angry at everything and the captcha's sucking so much (f- you hCaptcha), that I spent HOURS literal WEEKS during my summer break to make a bot that defeated captchas. I know it's possible, after all captcha's is just javascript ran in the browser that then asks the user to like pick the right images. Here's how I planned it:

  1. Find out what parts of the javascript is of importance
  2. Run it in a small js box using c# and mimicing a browser
  3. Figure out the captcha
  4. Show the captcha to the user in the Discord Lite application
  5. (user does the captcha)
  6. Figure out how to send data back to hCaptcha
  7. Profit?!?!! $$$

So yea, that was the idea. I've done this before. It's possible. BUTTTTT....
MORALS!
After all, this would be an opensource tool. Meaning that anyone could find the reimplementation of the reverse engineered apis of the captcha through my repository. Meaning that anyone could use it, may it be for good or bad.
ALSO! It would require a lot of maintenance. I remember from the previous time the javascript of hcaptcha gets updated 2 times a week, meaning that Discord Lite would need to get an update twice a week to make sure the way the hCaptcha apis are handled is up to date. That's something I don't want to do.

Also, since then all the requests for authentication comes from a program itself (and no browser used in between), there would be another issue. Cloudflare. Cloudflare has this thing called bot management. I don't know much about it, all I know is that you have to spoof JA3 fingerprints and TLS ciphers to bypass it. Honestly, as I said before, this is an opensource project. Having to write something like that is just something I don't want to morally do.

Solution 3: Authentication tokens

The last "solution" I could think of is just asking the user to paste in their authentication token into the program. This would make the program at lot less user friendly as the user would need to do some tech-savy only for people that know stuff coding tricks into their browser. But you know what? If they want a faster Discord, they might as well take that extra step (is what I thought).

Third step

The third step is all about data and connectivity:

  1. Connect to Discord
  2. Receive data

EZ right?!?!!

After some throwing around and getting angry at stuff, I finally managed to create a websocket connection to Discord and decipher what they're actually sending. Insane, I know. So Discord works with the usual "send whatever the frick you have, we'll send you back what you're missing" thing. So, at the beginning you send a dictionary to the websocket with keys like the chats, channels, users etc., just all being empty. Discord's websocker sends you a whole shit load of data back showing everything you miss. After saving that into your state dictionary, you will always receive updates from the webhook whenever something new comes up. Though, if you think you're missing something, you can ask Discord by just sending your whole ass state again and see what the websocket responds with.

COOL! Done, now let's see what the performance does.

<show picture of it being very very slow (I also don't have this screenshot anymore)>

Whaaaa?/!?!?!

I've literally spend HOURS writing all the DTOs to hold the data sent by the Discord websocket, and what do I get back in return??? A 3000% resource usage spike (relative to Discord)!!!! Wtf?? This isn't how we got married...

After playing around I found out that the spike only happens at the initial loading of all the data (you know when the websocket sends all of its crap and the JSON parser literally dies). In general, before and after this occurrence, the program reduces the resource usage up to 70% (yet again relative to Discord). I guess a minor win???? Finally...

Anyway, I decided to stop continuing on this project. The whole authentication token thing is too hard for the general user that just wants to save resources, and then spiking the program by 3000% seems a bit extravagant, ESPECIALLY when the user just wants to save resources




Whatever, if you're interested in the hocus pocus I've done, here's a link: click. It also contains like a very well written readme that explains the project a bit more on a bit more professional tone.