Skip to content
This repository has been archived by the owner on Oct 6, 2024. It is now read-only.

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
mrozio13pl committed Apr 2, 2024
0 parents commit 27096f4
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
Binary file added assets/discord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 115 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { request } from 'undici';
import prompts from '@mrozio/prompts';
import pc from 'picocolors';
import base64 from 'base-64';

const START_TIME = process.hrtime();
const VALIDATE_TOKEN_URL = 'https://discord.com/api/v9/explicit-media/current-version';
const OPEN_LOOTBOX_URL = 'https://discord.com/api/v9/users/@me/lootboxes/open';
const CLAIM_PRIZE_URL = 'https://discord.com/api/v9/users/@me/lootboxes/redeem-prize';
const X_SUPER = {
client_build_number: 280346
};
const X_SUPER_PROPERTIES = base64.encode(JSON.stringify(X_SUPER));

const ITEMS = {
'1214340999644446726': 'Quack!!',
'1214340999644446724': '⮕⬆⬇⮕⬆⬇',
'1214340999644446722': 'Wump Shell',
'1214340999644446720': 'Buster Blade',
'1214340999644446725': 'Power Helmet',
'1214340999644446723': 'Speed Boost',
'1214340999644446721': 'Cute Plushie',
'1214340999644446728': 'Dream Hammer',
'1214340999644446727': 'OHHHHH BANANA'
};

let { token } = await prompts({
type: 'password',
message: 'Paste your discord token:',
name: 'token',
validate: async token => {
const { statusCode } = await request(VALIDATE_TOKEN_URL, {
method: 'GET',
headers: {
Authorization: token.trim(),
'X-Super-Properties': X_SUPER_PROPERTIES
}
});

if (statusCode !== 200) return 'Token not valid!';

return true;
}
});

token = token?.trim(); // get rid of empty characters

if (!token) process.exit();

async function claimPrize() {
const { body } = await request(CLAIM_PRIZE_URL, {
method: 'POST',
headers: {
Authorization: token,
'X-Super-Properties': X_SUPER_PROPERTIES,
'Content-type': 'application/json'
}
});

const { redeemed_prize } = await body.json();
const END_TIME = process.hrtime(START_TIME);
const END_TIME_NANOSECONDS = END_TIME[0] * 1e9 + END_TIME[1];
const END_TIME_SECONDS = END_TIME_NANOSECONDS / 1e9;

if (redeemed_prize) {
console.log(pc.green(pc.bold('Successfully claimed the prize! 🎉')));
console.log('Time: %s seconds', END_TIME_SECONDS.toFixed(2));
} else {
console.log(pc.red('Failed to redeem the prize, retrying...'));
setTimeout(openLootbox, 5e3);
}
}

async function openLootbox() {
const { body } = await request(OPEN_LOOTBOX_URL, {
method: 'POST',
headers: {
Authorization: token,
'X-Super-Properties': X_SUPER_PROPERTIES,
'Content-type': 'application/json'
}
});

const { retry_after, opened_item, user_lootbox_data: { opened_items, redeemed_prize } } = await body.json();

if (retry_after) {
console.log(pc.red('You are being rate limited, retrying in %d seconds'), retry_after * 1e3);
setTimeout(openLootbox, retry_after);
return;
}

if (redeemed_prize) {
console.log(pc.yellow('You have already claimed the reward.'));
return;
}

const openedItemsCount = Object.keys(opened_items).length;

if (opened_items[opened_item] === 1) {
console.log(pc.yellow('NEW ITEM!'), pc.bold(ITEMS[opened_item]));
console.log(`${9 - openedItemsCount} items remaining.`);
} else {
console.log(pc.gray(`Got ${pc.bold(ITEMS[opened_item])} again. (${opened_items[opened_item]})`));
}

if (openedItemsCount >= 9) {
await claimPrize();
return;
}

setTimeout(openLootbox, 5e3); // cooldown is about 5 seconds
}

// start
openLootbox();
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "automated-discord-loot-boxes",
"private": true,
"author": "mrozio13pl",
"description": "Automatically opens discord loot boxes and claims the decoration reward, even without access to loot boxes!",
"type": "module",
"main": "index.js",
"scripts": {
"start": "node ."
},
"dependencies": {
"@mrozio/prompts": "^3.0.0",
"base-64": "^1.0.0",
"picocolors": "^1.0.0",
"undici": "^6.11.1"
}
}
33 changes: 33 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 🎁 Automated Discord Loot Boxes 🎁

Automatically opens discord loot boxes and claims the decoration reward, even __without access__ to loot boxes!

<img src="./assets/screenshot.png" alt="screenshot" />
<img src="./assets/discord.png" alt="discord" />

Even though for some people loot boxes may appear like they have been removed from Discord app, the API is still up and running, which means you can still get the profile decoration if you haven't already!

## Setup

1. Download this git repo.
2. Install [NodeJS](https://nodejs.org/) on your computer.
3. Open CMD in the directory where you have the repository installed.
4. Execute these commands:
```sh
npm install
npm start
```
5. Paste your discord token.

Done! 🎉

## Is it safe?

Probably yes, this program doesn't store your token anywhere. You have a higher chance of Discord banning you (for some reason), but the most likely won't care.

> 👉 Remember to never share your discord token!

<details>
<summary><h3>Disclaimer ⚠</h3></summary>
This code is provided for educational purposes only. Please do not use it in production environments without proper understanding and testing. Copy-pasting code without comprehension may lead to unintended consequences. Always ensure to review and understand the code before using it in any context. Use at your own risk.
</details>

0 comments on commit 27096f4

Please # to comment.