Начинающий
- Статус
- Оффлайн
- Регистрация
- 5 Ноя 2022
- Сообщения
- 78
- Реакции
- 3
- Выберите загрузчик игры
- Прочие моды
Всем привет, давненько уже небыло постов, обновленная версия парсинга шахт на фт 1.16.5
Бот на Mineflayer, который за тебя обходит все авто-шахты на mc.funtime.su и показывает когда и что сбросится.
Просто запускаешь — он логинится, телепортируется по варпам анархий, читает голограммы с редкостью и таймером сброса и выводит всё в консоль. Капчу тоже решает сам, если поднять локальный солвер.
Кому нужен - пожалуйста берите, критика приветствуется, говорить о том что мусор не нужно, повторюсь еще раз может кому то пригодится, не щас так потом.
Умеет
SS консоль (без убранной отладки/сохранения):
Коооод
Бот на Mineflayer, который за тебя обходит все авто-шахты на mc.funtime.su и показывает когда и что сбросится.
Просто запускаешь — он логинится, телепортируется по варпам анархий, читает голограммы с редкостью и таймером сброса и выводит всё в консоль. Капчу тоже решает сам, если поднять локальный солвер.
Кому нужен - пожалуйста берите, критика приветствуется, говорить о том что мусор не нужно, повторюсь еще раз может кому то пригодится, не щас так потом.
Умеет
- Обходит все настроенные анархии по кругу
- Читает редкость и время сброса шахты с голограмм
- Сам решает капчу через локальный HTTP-солвер
- При кике или ошибке переподключается через 15 секунд
- Никакого лишнего мусора в консоли
Для запуска- Node.js 18+
- Локальный солвер капч на Пожалуйста, авторизуйтесь для просмотра ссылки.(был выложен в прошлой моей теме)
SS консоль (без убранной отладки/сохранения):
Коооод
JavaScript:
// ============================================================
// ЗАВИСИМОСТИ
// ============================================================
const mineflayer = require('mineflayer');
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
const FlayerCaptcha = require('flayercaptcha');
// ============================================================
// КОНФИГУРАЦИЯ
// ============================================================
const CONFIG = {
host: 'mc.funtime.su',
version: '1.16.5',
username: 'YourNickname',
password: 'YourPassword',
captchaDir: 'captches',
captchaServer: 'http://127.0.0.1:15732/solve',
};
const DIRECTIONS = new Map([
['3 2', 'up'], ['3 -2', 'down'], ['3 0', 'south'],
['2 0', 'west'], ['0 0', 'north'], ['5 0', 'east']
]);
const DIRECTIONS_INVERSE = {
up: 'down', down: 'up',
south: 'north', north: 'south',
west: 'east', east: 'west'
};
const getViewDirection = (yaw, pitch) =>
DIRECTIONS_INVERSE[DIRECTIONS.get(`${Math.round(yaw)} ${Math.round(pitch)}`)];
// ============================================================
// СПИСОК АНАРХИЙ
// ============================================================
function generateRange(start, end) {
const result = [];
for (let i = start; i <= end; i++) result.push(i);
return result;
}
const ANARCHY_LIST = [
...generateRange(1001, 1006),
...generateRange(2001, 2016),
...generateRange(3001, 3008),
...generateRange(5001, 5004),
...generateRange(6001, 6003),
];
// ============================================================
// ИНИЦИАЛИЗАЦИЯ ПАПКИ ДЛЯ КАПЧ
// ============================================================
if (!fs.existsSync(CONFIG.captchaDir)) {
fs.mkdirSync(CONFIG.captchaDir);
console.log(`[INIT] Создана папка "${CONFIG.captchaDir}"`);
}
// ============================================================
// БОТ
// ============================================================
function startBot() {
let isRunning = true;
let isReconnecting = false;
let isParsing = false;
let currentIndex = 0;
const bot = mineflayer.createBot({
host: CONFIG.host,
username: CONFIG.username,
version: CONFIG.version,
hideErrors: true,
viewDistance: 2,
});
// ============================================================
// КАПЧА
// ============================================================
const captcha = new FlayerCaptcha(bot, { delay: 100 });
captcha.on('imageReady', async ({ data: captchaData, image }) => {
if (captchaData.facing === 'up' || captchaData.facing === 'down') return;
if (captchaData.minDistance > 5) return;
if (getViewDirection(bot.entity.yaw, bot.entity.pitch) !== captchaData.viewDirection) return;
const imagePath = path.join(CONFIG.captchaDir, `captcha_${CONFIG.username}.png`);
try {
await image.toFile(imagePath);
const formData = new FormData();
formData.append('file', fs.createReadStream(imagePath));
const { data } = await axios.post(CONFIG.captchaServer, formData, {
headers: formData.getHeaders(),
});
let result = '';
if (Array.isArray(data)) result = data.map(i => i.class_name || i).join('');
else if (typeof data === 'string') result = data;
else if (data && typeof data === 'object') result = data.result || data.text || data.code || '';
if (!result || result.trim() === '') {
console.log(`[КАПЧА] Пустой результат, пропускаю`);
return;
}
console.log(`[КАПЧА] Распознано: ${result}`);
setTimeout(() => bot.chat(result), 1000);
} catch (err) {
console.error(`[КАПЧА] Ошибка:`, err.message);
}
});
// ============================================================
// ПАРСИНГ ГОЛОГРАММ
// ============================================================
function extractMineData() {
const entities = Object.values(bot.entities);
const botPos = bot.entity.position;
let rare = null;
let timeTimestamp = null;
let foundMineHologram = false;
const nearby = entities.filter(e =>
(e.type === 'object' || e.name === 'armor_stand') &&
e.position.distanceTo(botPos) < 15 &&
e.metadata?.[2]
);
nearby.forEach(entity => {
try {
const json = JSON.parse(entity.metadata[2]);
const text = json.extra
? json.extra.map(i => i.text).join('')
: (json.text || '');
if (text.includes('Авто-Шахта')) foundMineHologram = true;
if (text.includes('Следующая:')) {
rare = text.replace('Следующая:', '').trim();
}
const timeMatch = text.match(/(\d{2}:\d{2})/);
if (timeMatch) {
const [min, sec] = timeMatch[1].split(':').map(Number);
timeTimestamp = Date.now() + (min * 60 + sec) * 1000;
}
} catch (_) {}
});
return { rare, timeTimestamp, foundMineHologram };
}
// ============================================================
// ЦИКЛ КОМАНД
// ============================================================
async function sendCommand() {
if (!isRunning) return;
if (currentIndex >= ANARCHY_LIST.length) {
console.log(`Все анархии обработаны, начинаю заново`);
currentIndex = 0;
}
const code = ANARCHY_LIST[currentIndex];
bot.chat(`/an${code}`);
await new Promise(r => setTimeout(r, 3000));
try {
let { rare, timeTimestamp, foundMineHologram } = extractMineData();
if (!rare || !timeTimestamp || !foundMineHologram) {
console.log(`Данные an${code} не найдены, телепортируюсь на /warp mine`);
bot.chat('/warp mine');
await new Promise(r => setTimeout(r, 10000));
({ rare, timeTimestamp, foundMineHologram } = extractMineData());
}
if (rare && timeTimestamp) {
console.log(`an${code} | Редкость: ${rare} | Сброс: ${new Date(timeTimestamp).toLocaleTimeString()}`);
} else {
console.log(`an${code} | Данные не получены`);
}
} catch (err) {
console.error(`Ошибка при an${code}:`, err.message);
}
currentIndex++;
setTimeout(sendCommand, 1000);
}
// ============================================================
// СОБЫТИЯ
// ============================================================
bot.on('message', (msg) => {
const message = msg.toString();
console.log(message);
if (message.includes('/login')) {
bot.chat(`/l ${CONFIG.password}`);
}
if (message.includes('Успешная авторизация') && !isParsing) {
console.log(`Авторизован. Начинаю через 2 сек...`);
isParsing = true;
setTimeout(sendCommand, 2000);
}
});
function handleDisconnect(reason) {
if (isReconnecting || !isRunning) return;
isReconnecting = true;
isRunning = false;
console.log(`Отключён (${reason}). Переподключение через 15 сек...`);
bot.quit();
setTimeout(startBot, 15000);
}
bot.on('kicked', (reason) => handleDisconnect(`kicked: ${reason}`));
bot.on('error', (err) => handleDisconnect(`error: ${err.message}`));
}
// ============================================================
// ЗАПУСК
// ============================================================
startBot();