q13x-eaglerproxy/server/proxy/skins/EaglerSkins.js
2024-09-04 12:02:00 +00:00

135 lines
5.8 KiB
JavaScript

import { Constants } from "../Constants.js";
import { Enums } from "../Enums.js";
import { MineProtocol } from "../Protocol.js";
import { Util } from "../Util.js";
import fetch from "node-fetch";
// TODO: convert all functions to use MineProtocol's UUID manipulation functions
export var EaglerSkins;
(function (EaglerSkins) {
async function skinUrlFromUuid(uuid) {
const response = (await (await fetch(`https://sessionserver.mojang.com/session/minecraft/profile/${uuid}`)).json());
const parsed = JSON.parse(Buffer.from(response.properties[0].value, "base64").toString());
return parsed.textures.SKIN.url;
}
EaglerSkins.skinUrlFromUuid = skinUrlFromUuid;
function downloadSkin(skinUrl) {
const url = new URL(skinUrl);
if (url.protocol != "https:" && url.protocol != "http:")
throw new Error("Invalid skin URL protocol!");
return new Promise(async (res, rej) => {
const skin = await fetch(skinUrl);
if (skin.status != 200) {
rej({
url: skinUrl,
status: skin.status,
});
return;
}
else {
res(Buffer.from(await skin.arrayBuffer()));
}
});
}
EaglerSkins.downloadSkin = downloadSkin;
function safeDownloadSkin(skinUrl, backoff) {
return new Promise((res, rej) => {
backoff.queueTask(async (err) => {
if (err)
return rej(err);
try {
res(await downloadSkin(skinUrl));
}
catch (err) {
if (err.status == 429)
throw new Error("Ratelimited!");
else
throw new Error("Unexpected HTTP status code: " + err.status);
}
});
});
}
EaglerSkins.safeDownloadSkin = safeDownloadSkin;
function readClientDownloadSkinRequestPacket(message) {
const ret = {
id: null,
uuid: null,
url: null,
};
const id = MineProtocol.readVarInt(message), uuid = MineProtocol.readUUID(id.newBuffer), url = MineProtocol.readString(uuid.newBuffer, 1);
ret.id = id.value;
ret.uuid = uuid.value;
ret.url = url.value;
return ret;
}
EaglerSkins.readClientDownloadSkinRequestPacket = readClientDownloadSkinRequestPacket;
function writeClientDownloadSkinRequestPacket(uuid, url) {
return Buffer.concat([[Enums.EaglerSkinPacketId.CFetchSkinReq], MineProtocol.writeUUID(uuid), [0x0], MineProtocol.writeString(url)].map((arr) => (arr instanceof Uint8Array ? arr : Buffer.from(arr))));
}
EaglerSkins.writeClientDownloadSkinRequestPacket = writeClientDownloadSkinRequestPacket;
function readServerFetchSkinResultBuiltInPacket(message) {
const ret = {
id: null,
uuid: null,
skinId: null,
};
const id = MineProtocol.readVarInt(message), uuid = MineProtocol.readUUID(id.newBuffer), skinId = MineProtocol.readVarInt(id.newBuffer.subarray(id.newBuffer.length));
ret.id = id.value;
ret.uuid = uuid.value;
ret.skinId = skinId.value;
return this;
}
EaglerSkins.readServerFetchSkinResultBuiltInPacket = readServerFetchSkinResultBuiltInPacket;
function writeServerFetchSkinResultBuiltInPacket(uuid, skinId) {
uuid = typeof uuid == "string" ? Util.uuidStringToBuffer(uuid) : uuid;
return Buffer.concat([Buffer.from([Enums.EaglerSkinPacketId.SFetchSkinBuiltInRes]), uuid, Buffer.from([skinId >> 24, skinId >> 16, skinId >> 8, skinId & 0xff])]);
}
EaglerSkins.writeServerFetchSkinResultBuiltInPacket = writeServerFetchSkinResultBuiltInPacket;
function readServerFetchSkinResultCustomPacket(message) {
const ret = {
id: null,
uuid: null,
skin: null,
};
const id = MineProtocol.readVarInt(message), uuid = MineProtocol.readUUID(id.newBuffer), skin = uuid.newBuffer.subarray(0, Constants.EAGLERCRAFT_SKIN_CUSTOM_LENGTH);
ret.id = id.value;
ret.uuid = uuid.value;
ret.skin = skin;
return this;
}
EaglerSkins.readServerFetchSkinResultCustomPacket = readServerFetchSkinResultCustomPacket;
function writeClientFetchEaglerSkin(uuid, url) {
uuid = typeof uuid == "string" ? Util.uuidStringToBuffer(uuid) : uuid;
return Buffer.concat([[Enums.EaglerSkinPacketId.CFetchSkinEaglerPlayerReq], uuid, [0x00], MineProtocol.writeString(url)].map((arr) => (arr instanceof Uint8Array ? arr : Buffer.from(arr))));
}
EaglerSkins.writeClientFetchEaglerSkin = writeClientFetchEaglerSkin;
function writeServerFetchSkinResultCustomPacket(uuid, skin, downloaded) {
uuid = typeof uuid == "string" ? Util.uuidStringToBuffer(uuid) : uuid;
return Buffer.concat([
[Enums.EaglerSkinPacketId.SFetchSkinRes],
uuid,
[-1], // TODO: if buggy, use 0xff instead
skin.subarray(0, Constants.EAGLERCRAFT_SKIN_CUSTOM_LENGTH),
].map((arr) => (arr instanceof Uint8Array ? arr : Buffer.from(arr))));
}
EaglerSkins.writeServerFetchSkinResultCustomPacket = writeServerFetchSkinResultCustomPacket;
function readClientFetchEaglerSkinPacket(buff) {
const ret = {
id: null,
uuid: null,
};
const id = MineProtocol.readVarInt(buff), uuid = MineProtocol.readUUID(id.newBuffer);
ret.id = id.value;
ret.uuid = uuid.value;
return ret;
}
EaglerSkins.readClientFetchEaglerSkinPacket = readClientFetchEaglerSkinPacket;
class EaglerSkin {
owner;
type;
// update this over time
builtInSkin;
skin;
}
EaglerSkins.EaglerSkin = EaglerSkin;
})(EaglerSkins || (EaglerSkins = {}));