update: add AFK bot implementation with logging and teleport detection
This commit is contained in:
parent
e68f15f1c7
commit
b347e0a984
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/node_modules
|
||||
package-lock.json
|
||||
.env
|
||||
.env
|
||||
*.log
|
||||
146
afk.js
Normal file
146
afk.js
Normal file
@ -0,0 +1,146 @@
|
||||
const mineflayer = require("mineflayer");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
// Configuration
|
||||
const BOT_CONFIG = {
|
||||
host: "java.donutsmp.net",
|
||||
username: "AFKBot",
|
||||
auth: "microsoft",
|
||||
version: "1.21.1",
|
||||
};
|
||||
|
||||
const LOG_FILE = path.join(__dirname, "afk.log");
|
||||
const TELEPORT_DETECT_REGEX = /you teleported to\b/i;
|
||||
|
||||
// Logging
|
||||
function log(message) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const logMessage = `[${timestamp}] ${message}`;
|
||||
console.log(logMessage);
|
||||
fs.appendFileSync(LOG_FILE, logMessage + "\n");
|
||||
}
|
||||
|
||||
function toPlainText(value) {
|
||||
if (value == null) return "";
|
||||
if (typeof value === "string") return value;
|
||||
if (
|
||||
typeof value.toString === "function" &&
|
||||
value.toString !== Object.prototype.toString
|
||||
) {
|
||||
const asString = value.toString();
|
||||
if (asString && asString !== "[object Object]") return asString;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(toPlainText).join("");
|
||||
}
|
||||
|
||||
if (typeof value === "object") {
|
||||
let text = "";
|
||||
if (typeof value.text === "string") text += value.text;
|
||||
if (typeof value.translate === "string") text += value.translate;
|
||||
if (Array.isArray(value.with)) text += value.with.map(toPlainText).join("");
|
||||
if (Array.isArray(value.extra))
|
||||
text += value.extra.map(toPlainText).join("");
|
||||
return text;
|
||||
}
|
||||
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function logIfTeleport(source, text) {
|
||||
const normalized = String(text || "").trim();
|
||||
if (!normalized) return;
|
||||
if (!TELEPORT_DETECT_REGEX.test(normalized)) return;
|
||||
log(`Teleport detected from ${source}: ${normalized}`);
|
||||
}
|
||||
|
||||
// Create bot
|
||||
const bot = mineflayer.createBot({
|
||||
host: BOT_CONFIG.host,
|
||||
username: BOT_CONFIG.username,
|
||||
auth: BOT_CONFIG.auth,
|
||||
version: BOT_CONFIG.version,
|
||||
});
|
||||
|
||||
// Event handlers
|
||||
bot.on("login", () => {
|
||||
log("Bot logged in");
|
||||
bot.setControlState("forward", false);
|
||||
});
|
||||
|
||||
bot.on("spawn", () => {
|
||||
log("Bot spawned");
|
||||
});
|
||||
|
||||
bot.on("error", (err) => {
|
||||
log(`Error: ${err.message}`);
|
||||
});
|
||||
|
||||
bot.on("kicked", (reason) => {
|
||||
log(`Kicked: ${reason}`);
|
||||
});
|
||||
|
||||
bot.on("end", () => {
|
||||
log("Bot disconnected");
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
bot.on("chat", (username, message) => {
|
||||
if (username === bot.username) return;
|
||||
log(`Chat [${username}]: ${message}`);
|
||||
logIfTeleport("chat", message);
|
||||
});
|
||||
|
||||
bot.on("messagestr", (message, position) => {
|
||||
if (!message) return;
|
||||
|
||||
if (position === "game_info") {
|
||||
log(`Hotbar: ${message}`);
|
||||
}
|
||||
|
||||
logIfTeleport(`messagestr${position ? `:${position}` : ""}`, message);
|
||||
});
|
||||
|
||||
bot.on("message", (jsonMsg, position) => {
|
||||
const text = toPlainText(jsonMsg);
|
||||
if (!text) return;
|
||||
|
||||
if (position === "game_info") {
|
||||
log(`Hotbar(json): ${text}`);
|
||||
}
|
||||
|
||||
logIfTeleport(`message${position ? `:${position}` : ""}`, text);
|
||||
});
|
||||
|
||||
// Fallback packet hooks for title/actionbar channels on servers that do not
|
||||
// emit teleport text through regular chat events.
|
||||
bot._client.on("set_action_bar_text", (packet) => {
|
||||
const text = toPlainText(packet?.text);
|
||||
if (!text) return;
|
||||
log(`ActionBar: ${text}`);
|
||||
logIfTeleport("actionbar", text);
|
||||
});
|
||||
|
||||
bot._client.on("set_title_text", (packet) => {
|
||||
const text = toPlainText(packet?.text);
|
||||
if (!text) return;
|
||||
log(`Title: ${text}`);
|
||||
logIfTeleport("title", text);
|
||||
});
|
||||
|
||||
bot._client.on("set_subtitle_text", (packet) => {
|
||||
const text = toPlainText(packet?.text);
|
||||
if (!text) return;
|
||||
log(`Subtitle: ${text}`);
|
||||
logIfTeleport("subtitle", text);
|
||||
});
|
||||
|
||||
// Graceful shutdown
|
||||
process.on("SIGINT", () => {
|
||||
log("Shutdown signal received");
|
||||
bot.quit();
|
||||
});
|
||||
|
||||
log("Starting AFK bot...");
|
||||
Loading…
x
Reference in New Issue
Block a user