mcraft-fun-mineflayer
Version:
Mineflayer viewer (connector) for mcraft.fun project and vanilla Minecraft client! Both TCP and WebSockets servers are supported.
156 lines (155 loc) • 6.21 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MineflayerPacketHandler = void 0;
const utils_1 = require("@zardoy/flying-squid/dist/utils");
const prismarine_item_1 = __importDefault(require("prismarine-item"));
const generalPacketsProxy_1 = require("./generalPacketsProxy");
const entity_1 = require("./replicator/entity");
const customChannel_1 = require("./customChannel");
class MineflayerPacketHandler {
bot;
auxClientsState;
Item;
auxHelpers;
loginState = '';
onClientJoin = [];
constructor(bot, auxClientsState) {
this.bot = bot;
this.auxClientsState = auxClientsState;
this.Item = (0, prismarine_item_1.default)(bot.version);
this.setupPacketListeners();
this.auxHelpers = (0, generalPacketsProxy_1.handleAuxClientsProxy)(this.bot._client, this.auxClientsState);
const oldWrite = this.bot._client.write.bind(this.bot._client);
this.bot._client.write = (name, data) => {
oldWrite(name, data);
this.auxHelpers.writeMainClientPackets(name, data);
};
const { onClientJoin } = (0, entity_1.entityReplicator)(this.bot);
this.onClientJoin.push(onClientJoin);
}
setupPacketListeners() {
// this.bot.on('move', () => {
// this.updateHealth()
// })
this.bot.on('health', () => {
this.updateHealth();
});
this.patchBotMethods();
}
writeClients(name, data, clients) {
this.auxHelpers.writeToAuxClients(name, data, clients);
}
patchBotMethods() {
const hookMethod = (_name, callback) => {
const name = _name;
const oldMethod = this.bot[name].bind(this.bot);
this.bot[name] = (...args) => {
callback(...args);
oldMethod(...args);
};
};
hookMethod('closeWindow', () => {
this.writeClients('closeWindow', {
windowId: 0
});
});
hookMethod('setQuickBarSlot', () => {
this.updateSlot();
});
}
updateSlot(clients) {
this.writeClients('held_item_slot', { slot: this.bot.quickBarSlot }, clients);
}
updateHealth(clients) {
this.writeClients('update_health', {
food: this.bot.food,
foodSaturation: this.bot.foodSaturation,
health: this.bot.health
}, clients);
}
handleNewConnection(client) {
if (!this.auxHelpers.lastPackets.login || !this.bot.entity) {
let reason = `Bot was not logged in yet ${this.loginState}`;
if (!this.bot.entity) {
reason += `\nMineflayer issue: bot.entity is undefined`;
}
if (!this.bot.entity) {
reason += `\nMineflayer issue: bot.entity is undefined`;
}
if (!this.auxHelpers.lastPackets.login) {
reason += `\nLogin packet was not received`;
}
client.writeChannel(customChannel_1.CHANNEL_NAME, JSON.stringify({
type: 'kick',
reason: reason
}));
client.end(reason);
return;
}
this.auxHelpers.onNewAuxConnection(client);
this.auxHelpers.lastPackets.login.gameMode = this.bot.game.gameMode;
this.updateSlot([client]);
this.updateHealth([client]);
client.write('abilities', {
flags: 0,
walkingSpeed: 0,
flyingSpeed: 0
});
client.write('window_items', {
windowId: 0,
stateId: 1,
items: this.bot.inventory.slots.map(item => this.Item.toNotch(item)),
carriedItem: this.Item.toNotch(this.bot.heldItem)
});
this.sendChunks(client);
this.onClientJoin.forEach(onClientJoin => onClientJoin(client));
client.write('player_info', this.auxHelpers.firstPackets.player_info);
}
debug(...args) {
// console.log(...args)
}
sendChunks(client) {
this.debug(`sending chunks to new client viewer`);
const botChunk = this.bot.entity.position.floored().scale(1 / 16).floored();
for (const [xRel, zRel] of (0, utils_1.generateSpiralMatrix)(8)) {
const x = xRel + botChunk.x;
const z = zRel + botChunk.z;
const chunk = this.bot.world.getColumn(x, z);
if (!chunk)
continue;
const dumpedLights = chunk.dumpLight();
const newLightsFormat = this.bot.supportFeature('newLightingDataFormat');
const newLightsData = newLightsFormat ? { skyLight: dumpedLights.skyLight, blockLight: dumpedLights.blockLight } : undefined;
const chunkBuffer = chunk.dump();
const bitMap = chunk.getMask();
client.write('map_chunk', {
x,
z,
groundUp: bitMap !== undefined ? true : undefined,
trustEdges: true,
bitMap: bitMap,
biomes: chunk.dumpBiomes(),
ignoreOldData: true,
heightmaps: {
type: 'compound',
name: '',
value: {
MOTION_BLOCKING: { type: 'longArray', value: new Array(this.bot.supportFeature('dimensionDataIsAvailable') ? 37 : 36).fill([0, 0]) },
WORLD_SURFACE: { type: 'longArray', value: new Array(this.bot.supportFeature('dimensionDataIsAvailable') ? 37 : 36).fill([0, 0]) },
}
},
chunkData: chunkBuffer,
blockEntities: [],
skyLightMask: chunk.skyLightMask,
emptySkyLightMask: chunk.emptySkyLightMask,
blockLightMask: chunk.blockLightMask,
emptyBlockLightMask: chunk.emptyBlockLightMask,
...newLightsData
});
}
}
}
exports.MineflayerPacketHandler = MineflayerPacketHandler;