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

Commit

Permalink
MojangAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
RadiatedExodus committed Dec 29, 2023
1 parent 557037a commit d0d8411
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 2 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@discordjs/voice": "^0.14.0",
"@prisma/client": "^5.2.0",
"@types/ms": "^0.7.32",
"axios": "^1.6.3",
"chalk": "4.0.0",
"discord-player": "6.5.0",
"discord.js": "^14.6.0",
Expand Down
111 changes: 111 additions & 0 deletions src/commands/Info/MojangAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { SlashCommandBuilder } from "discord.js";
import type { MeteoriumCommand } from "..";
import { MeteoriumEmbedBuilder } from "../../util/MeteoriumEmbedBuilder";
import * as MojangAPI from "../../util/MojangAPI";

export const Command: MeteoriumCommand = {
InteractionData: new SlashCommandBuilder()
.setName("mojangapi")
.setDescription("Get Minecraft information from Mojang APIs")
.addSubcommandGroup((group) =>
group
.setName("profile")
.setDescription("Get a user's profile information")
.addSubcommand((subcommand) =>
subcommand
.setName("username")
.setDescription("By username")
.addStringOption((option) =>
option.setName("username").setDescription("The username of the player").setRequired(true),
)
.addBooleanOption((option) =>
option
.setName("ephemeral")
.setDescription("If true, the response will only be shown to you")
.setRequired(false),
),
)
.addSubcommand((subcommand) =>
subcommand
.setName("uuid")
.setDescription("By uuid")
.addStringOption((option) =>
option.setName("uuid").setDescription("The uuid of the player").setRequired(true),
)
.addBooleanOption((option) =>
option
.setName("ephemeral")
.setDescription("If true, the response will only be shown to you")
.setRequired(false),
),
),
),
async Callback(interaction, _) {
const Ephemeral = interaction.options.getBoolean("ephemeral", false) ? true : false;
await interaction.deferReply({ ephemeral: Ephemeral });

const SubcommandGroup = interaction.options.getSubcommandGroup();
const Subcommand = interaction.options.getSubcommand();

switch (SubcommandGroup) {
case "profile": {
let UUID: string;
if (Subcommand == "uuid") UUID = interaction.options.getString("uuid", true);
else {
const res = await MojangAPI.getUUIDFromName(interaction.options.getString("name", true));
if (res.code == 204 || res.code == 404)
return await interaction.editReply("The username/profiile doesn't exist.");
if (res.code != 200)
return await interaction.editReply(
"Failed while fetching information from Mojang's API (username to uuid status code not 200)",
);
UUID = res.data.id;
}

const Profile = await MojangAPI.getProfile(UUID);
if (Profile.code != 200)
return await interaction.editReply(
"Failed while fetching information from Mojang's API (username to uuid status code not 200)",
);
const ProfileTextures = MojangAPI.decodeTexturesB64(Profile.data.properties[0].value);

const Embed = new MeteoriumEmbedBuilder()
.setNormalColor()
.setTitle(Profile.data.name)
.addFields([
{ name: "UUID", value: Profile.data.id },
{
name: "Profile actions",
value:
Profile.data.profileActions.length == 0
? "N/A"
: Profile.data.profileActions.toString(),
},
{
name: "Skin url",
value:
ProfileTextures.textures.SKIN == undefined
? `Default (${MojangAPI.decodeDefaultSkin(UUID)})`
: ProfileTextures.textures.SKIN.url,
},
{
name: "Skin type",
value:
ProfileTextures.textures.SKIN == undefined
? "N/A"
: ProfileTextures.textures.SKIN.metadata == undefined
? "Classic"
: "Slim",
},
{
name: "Cape url",
value:
ProfileTextures.textures.CAPE == undefined ? "N/A" : ProfileTextures.textures.CAPE.url,
},
]);

return await interaction.editReply({ embeds: [ Embed ] });
}
}
},
};
34 changes: 34 additions & 0 deletions src/util/MojangAPI/Proto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export interface Textures {
timestamp: string;
profileId: string;
profileName: string;
signatureRequired?: true;
textures: {
SKIN?: {
url: string;
metadata?: { model: string };
};
CAPE?: { url: string };
};
}

export interface ProfileResponse {
id: string;
name: string;
properties: [
{
name: "textures";
value: string;
signature?: string;
},
];
profileActions: string[];
legacy?: true;
}

export interface UUIDFromNameResponse {
name: string;
id: string;
legacy?: true;
demo?: true;
}
25 changes: 25 additions & 0 deletions src/util/MojangAPI/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import axios from "axios";

import * as proto from "./Proto";

export async function getUUIDFromName(name: string) {
const res = await axios.get(`https://api.mojang.com/users/profiles/minecraft/${name}`);
return { code: res.status, data: res.data as proto.UUIDFromNameResponse };
}

export async function getProfile(uuid: string) {
const res = await axios.get(`https://sessionserver.mojang.com/session/minecraft/profile/${encodeURIComponent(uuid)}`);
return { code: res.status, data: res.data as proto.ProfileResponse };
}

export function decodeTexturesB64(texturesb64: string) {
const bf = Buffer.from(texturesb64, "base64");
return JSON.parse(bf.toString()) as proto.Textures;
}

export function decodeDefaultSkin(uuid: string): "steve" | "alex" {
const chars = uuid.split("");
// @ts-ignore
const lsbs_even = parseInt(chars[ 7], 16) ^ parseInt(chars[15], 16) ^ parseInt(chars[23], 16) ^ parseInt(chars[31], 16);
return lsbs_even ? "alex" : "steve";
}
27 changes: 25 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,15 @@ axios@^0.21.4:
dependencies:
follow-redirects "^1.14.0"

axios@^1.6.3:
version "1.6.3"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.3.tgz#7f50f23b3aa246eff43c54834272346c396613f4"
integrity sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
Expand Down Expand Up @@ -453,7 +462,7 @@ color-support@^1.1.2:
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==

combined-stream@^1.0.6, combined-stream@~1.0.6:
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
Expand Down Expand Up @@ -760,7 +769,7 @@ find-up@^3.0.0:
dependencies:
locate-path "^3.0.0"

follow-redirects@^1.14.0:
follow-redirects@^1.14.0, follow-redirects@^1.15.0:
version "1.15.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
Expand All @@ -770,6 +779,15 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==

form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"

form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
Expand Down Expand Up @@ -1339,6 +1357,11 @@ prisma@^5.2.0:
dependencies:
"@prisma/engines" "5.6.0"

proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==

psl@^1.1.28:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
Expand Down

0 comments on commit d0d8411

Please sign in to comment.