mirror of
https://github.com/WorldEditAxe/eaglerproxy.git
synced 2024-11-24 06:26:05 -08:00
Skins actually work now
This commit is contained in:
parent
b9b7f6528f
commit
2e2969c551
|
@ -8,8 +8,7 @@ export enum EaglerPacketId {
|
||||||
SKIN = 0x07,
|
SKIN = 0x07,
|
||||||
C_READY = 0x08,
|
C_READY = 0x08,
|
||||||
COMPLETE_HANDSHAKE = 0x09,
|
COMPLETE_HANDSHAKE = 0x09,
|
||||||
DISCONNECT = 0xff,
|
DISCONNECT = 0xff
|
||||||
CUSTOM_PLAYER_LIST_ADD_PACKET = 0x38
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DisconnectReason {
|
export enum DisconnectReason {
|
||||||
|
@ -40,31 +39,6 @@ export type SkinCustom = [EaglerPacketId.SKIN, number, string, number, PrefixedS
|
||||||
export type ClientReady = [EaglerPacketId.C_READY]
|
export type ClientReady = [EaglerPacketId.C_READY]
|
||||||
export type Joined = [EaglerPacketId.COMPLETE_HANDSHAKE]
|
export type Joined = [EaglerPacketId.COMPLETE_HANDSHAKE]
|
||||||
export type Disconnect = [EaglerPacketId.DISCONNECT, number, string, DisconnectReason]
|
export type Disconnect = [EaglerPacketId.DISCONNECT, number, string, DisconnectReason]
|
||||||
export type PlayerList = [
|
|
||||||
EaglerPacketId.CUSTOM_PLAYER_LIST_ADD_PACKET,
|
|
||||||
UUID, 0xD6, 0x91, 0x9F, 0xD2,
|
|
||||||
/* username */ number, string, number, // 2nd number in string is 0x02, probably number of strings?
|
|
||||||
number, string, // string in this is "textures"
|
|
||||||
number, typeof PlayerListJson1, // base64 encoded string (see PlayerListJson1 for json contents)
|
|
||||||
number, typeof PlayerListBase64Str, // base64 encoded string ()
|
|
||||||
number, string, // string is isEaglerPlayer
|
|
||||||
number, string, // boolean
|
|
||||||
0x00, 0x01, 0x00, 0x00 // 256
|
|
||||||
]
|
|
||||||
export const PlayerListJson1 = {
|
|
||||||
timestamp: null, // UNIX, in MS
|
|
||||||
profileId: '65a4a3d370cb49bbad67f10086f1c543',
|
|
||||||
profileName: 'lax1dude',
|
|
||||||
signatureRequired: true,
|
|
||||||
textures: {
|
|
||||||
SKIN: {
|
|
||||||
url: 'http://textures.minecraft.net/texture/d46393de83fbe165ab680a1821aad9f07d08b8196b2429fa046a15b61b129dc4'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const PlayerListBase64Str = "¬X1eTQrruDPy+qp5pBNo+zIoPXGdhJKkhtPPgKIcBzgBDcp/CXhbcZong7886HSQyA2YMDL+muRgY+GLri+QH0wF5yZC5S1Nm8GrPPMScrWsgZRtyIv/cZnIQUtRAS4SQroup3M42s3blUjGjTfkjWTy5xxuHGaiXpgI1wAjsONfJebNLe+v3DvO2/7sbmMSQTEduODhF8J1QL44aiL5mAZFV+4XMzRVrs3wsIScwPaCSXqLRudn2tLRC5fylejnq5S9AHz17bDlwyWmMeG5djusM3ZVjYKfu3Bi/vEhG9eEyWhBxcDKilrXJ1ZwOeotwgwnafY4OLc18fS7w1LxHkedZLs/8gHZOpUQHcx2Kxhib5BOdRDMae+AuDRbR9Lk33txzYNlOS6drxHkpEyRwFTu7RYTQUIE+0Dljk4mZDqnTSd5ZDwb45FfYvm25nEu2r5hPj/UNUCAPTToNTCABWvWWuigVjt8pvATV05KPlzTl6bWqrLn822upkC3joP+H+GVR8TkdkGzyyjDbndt1hTXW+zIuB2og2oMuHAO5kI6JtEl26wk7eNYmBr4va6UpiEXAhYa10nRny+Fu9gHCHgMCW7n50+gK3IOAzxLt0QkrlYXgJI6uh5f125g/yMe7v5y49VpHwDcPkYBLcX0L9lxJh8EQem6ff8SLjcAwmdU="
|
|
||||||
|
|
||||||
// Afterwards, forward 0x01 (Join Game, Clientbound) and everything after that
|
|
||||||
|
|
||||||
// EAGLERCRAFT SKIN PROTOCOL
|
// EAGLERCRAFT SKIN PROTOCOL
|
||||||
// All Eaglercraft skin networking is done through plugin channels under the channel name EAG|Skins-1.8.
|
// All Eaglercraft skin networking is done through plugin channels under the channel name EAG|Skins-1.8.
|
||||||
|
|
|
@ -92,8 +92,9 @@ export function encodeSSkinDl(uuid: string | Buffer, skin: Buffer, isFetched: bo
|
||||||
// eaglercraft clients always expect a 16385 byte long byte array for the skin
|
// eaglercraft clients always expect a 16385 byte long byte array for the skin
|
||||||
if (!isFetched) skin = skin.length !== 16384 ? skin.length < 16384 ? Buffer.concat([Buffer.alloc(16384 - skin.length), skin]) : skin.subarray(16383) : skin
|
if (!isFetched) skin = skin.length !== 16384 ? skin.length < 16384 ? Buffer.concat([Buffer.alloc(16384 - skin.length), skin]) : skin.subarray(16383) : skin
|
||||||
else skin = skin.length !== 16384 ? skin.length < 16384 ? Buffer.concat([skin, Buffer.alloc(16384 - skin.length)]) : skin.subarray(16383) : skin
|
else skin = skin.length !== 16384 ? skin.length < 16384 ? Buffer.concat([skin, Buffer.alloc(16384 - skin.length)]) : skin.subarray(16383) : skin
|
||||||
const skinLen = encodeVarInt(skin.length), buff = Buffer.alloc(1 + 16 + 1 + skin.length)
|
const buff = Buffer.alloc(1 + 16 + 1 + skin.length)
|
||||||
buff.set([EaglerSkinPacketId.S_SKIN_DL, ...uuid, 0xff,...skin])
|
if (!isFetched) buff.set([EaglerSkinPacketId.S_SKIN_DL,...uuid, 0xff,...skin])
|
||||||
|
else buff.set([EaglerSkinPacketId.S_SKIN_DL, ...uuid, 0x00, ...skin])
|
||||||
return buff
|
return buff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,21 +121,48 @@ export function encodeCSkinReq(uuid: string | Buffer, url: string): Buffer {
|
||||||
return buff
|
return buff
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix broken custom skins
|
const SEG_SIZE = 3
|
||||||
|
|
||||||
export async function fetchSkin(url: string): Promise<Buffer> {
|
function invert(buff: Buffer): Buffer {
|
||||||
|
let buffers: Buffer[] = [], i = 0
|
||||||
|
const newBuffer = Buffer.alloc(buff.length)
|
||||||
|
while (true) {
|
||||||
|
if (i >= buff.length)
|
||||||
|
break
|
||||||
|
newBuffer.set(buff.subarray(i, i + 4).reverse(), i)
|
||||||
|
i += 4
|
||||||
|
}
|
||||||
|
return newBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
async function genRGBAEagler(buff: Buffer): Promise<Buffer> {
|
||||||
|
const r = await sharp(buff).extractChannel('red').raw({ depth: 'uchar' }).toBuffer()
|
||||||
|
const g = await sharp(buff).extractChannel('green').raw({ depth: 'uchar' }).toBuffer()
|
||||||
|
const b = await sharp(buff).extractChannel('blue').raw({ depth: 'uchar' }).toBuffer()
|
||||||
|
const a = await sharp(buff).ensureAlpha().extractChannel(3).toColorspace('b-w').raw({ depth: 'uchar' }).toBuffer()
|
||||||
|
const newBuff = Buffer.alloc(64 ** 2 * 4)
|
||||||
|
for (let i = 1; i < 64 ** 2; i++) {
|
||||||
|
const bytePos = i * 4
|
||||||
|
newBuff[bytePos] = a[i]
|
||||||
|
newBuff[bytePos + 1] = b[i]
|
||||||
|
newBuff[bytePos + 2] = g[i]
|
||||||
|
newBuff[bytePos + 3] = r[i]
|
||||||
|
}
|
||||||
|
return newBuff
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toEaglerSkin(buff: Buffer): Promise<Buffer> {
|
||||||
|
return genRGBAEagler(buff)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchSkin(url: string, process?: boolean): Promise<Buffer> {
|
||||||
return new Promise<Buffer>((res, rej) => {
|
return new Promise<Buffer>((res, rej) => {
|
||||||
let body = []
|
let body = []
|
||||||
request({ url: url, encoding: null }, (err, response, body) => {
|
request({ url: url, encoding: null }, (err, response, body) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
rej(err)
|
rej(err)
|
||||||
} else {
|
} else {
|
||||||
sharp(body)
|
toEaglerSkin(body).then(buff => res(buff))
|
||||||
.resize(64, 64)
|
|
||||||
.raw({ depth: 'char' })
|
|
||||||
.toBuffer()
|
|
||||||
.then(res)
|
|
||||||
.catch(rej)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user