Update bot.js
Browse files
bot.js
CHANGED
|
@@ -165,7 +165,7 @@ function createBot() {
|
|
| 165 |
return results;
|
| 166 |
}
|
| 167 |
|
| 168 |
-
// window.title parse
|
| 169 |
function parseWindowTitleToString(titleObj) {
|
| 170 |
try {
|
| 171 |
if (!titleObj) return "";
|
|
@@ -199,72 +199,6 @@ function createBot() {
|
|
| 199 |
}
|
| 200 |
}
|
| 201 |
|
| 202 |
-
// beefSlot inspect: daha derin ve [Object] yerine gerçek içeriği açacak şekilde
|
| 203 |
-
function inspectBeefSlot(slot) {
|
| 204 |
-
try {
|
| 205 |
-
if (!slot) return { inspected: "slot=null", nbtSummary: "nbt=null" };
|
| 206 |
-
|
| 207 |
-
// util.inspect ile depth:null ve maxArrayLength:null kullanarak tam açılım al
|
| 208 |
-
const inspected = util.inspect(slot, { depth: null, maxArrayLength: null });
|
| 209 |
-
|
| 210 |
-
// Ayrıca componentMap ve components içeriğini JSON'lanabilir hale getir
|
| 211 |
-
function simplify(obj, seen = new WeakSet()) {
|
| 212 |
-
if (obj == null) return obj;
|
| 213 |
-
if (typeof obj === "string" || typeof obj === "number" || typeof obj === "boolean") return obj;
|
| 214 |
-
if (seen.has(obj)) return "[Circular]";
|
| 215 |
-
if (Array.isArray(obj)) {
|
| 216 |
-
seen.add(obj);
|
| 217 |
-
return obj.map(i => simplify(i, seen));
|
| 218 |
-
}
|
| 219 |
-
if (obj instanceof Map) {
|
| 220 |
-
const out = {};
|
| 221 |
-
seen.add(obj);
|
| 222 |
-
for (const [k, v] of obj.entries()) {
|
| 223 |
-
out[String(k)] = simplify(v, seen);
|
| 224 |
-
}
|
| 225 |
-
return out;
|
| 226 |
-
}
|
| 227 |
-
if (typeof obj === "object") {
|
| 228 |
-
seen.add(obj);
|
| 229 |
-
const out = {};
|
| 230 |
-
for (const key of Object.keys(obj)) {
|
| 231 |
-
try {
|
| 232 |
-
out[key] = simplify(obj[key], seen);
|
| 233 |
-
} catch (e) {
|
| 234 |
-
out[key] = "[Error]";
|
| 235 |
-
}
|
| 236 |
-
}
|
| 237 |
-
return out;
|
| 238 |
-
}
|
| 239 |
-
try {
|
| 240 |
-
return String(obj);
|
| 241 |
-
} catch (e) {
|
| 242 |
-
return "[Unknown]";
|
| 243 |
-
}
|
| 244 |
-
}
|
| 245 |
-
|
| 246 |
-
let nbtSummary = "nbt=null";
|
| 247 |
-
try {
|
| 248 |
-
if (slot.nbt) {
|
| 249 |
-
// slot.nbt genelde bir NBT objesi; simplify ile okunur hale getir
|
| 250 |
-
nbtSummary = JSON.stringify(simplify(slot.nbt), null, 2);
|
| 251 |
-
} else {
|
| 252 |
-
// bazı sunucularda nbt null, ama components/componentMap taşıyor
|
| 253 |
-
const comp = {};
|
| 254 |
-
if (slot.components) comp.components = simplify(slot.components);
|
| 255 |
-
if (slot.componentMap) comp.componentMap = simplify(slot.componentMap);
|
| 256 |
-
nbtSummary = JSON.stringify(comp, null, 2);
|
| 257 |
-
}
|
| 258 |
-
} catch (e) {
|
| 259 |
-
nbtSummary = util.inspect(slot.nbt || slot.components || slot.componentMap, { depth: null, maxArrayLength: null });
|
| 260 |
-
}
|
| 261 |
-
|
| 262 |
-
return { inspected, nbtSummary };
|
| 263 |
-
} catch (err) {
|
| 264 |
-
return { inspected: "inspect-hata", nbtSummary: "inspect-hata" };
|
| 265 |
-
}
|
| 266 |
-
}
|
| 267 |
-
|
| 268 |
// --- Güvenli activate (öncelikle activateEntityAt kullanır, retry ve lookAt içerir) ---
|
| 269 |
async function safeActivateEntityPreferAt(entity, options = {}) {
|
| 270 |
const maxRetries = options.maxRetries ?? 3;
|
|
@@ -360,20 +294,18 @@ function createBot() {
|
|
| 360 |
});
|
| 361 |
}
|
| 362 |
|
| 363 |
-
// ---
|
| 364 |
function extractMinyonCanFromSlot(slot) {
|
| 365 |
try {
|
| 366 |
if (!slot) return null;
|
| 367 |
|
| 368 |
// 1) Eğer slot.nbt varsa önce oradan dene (çeşitli yollar)
|
| 369 |
if (slot.nbt) {
|
| 370 |
-
// Bazı sunucular nbt içinde display.Lore gibi tutuyor
|
| 371 |
try {
|
| 372 |
-
// Denenecek yollar
|
| 373 |
const candidates = [
|
| 374 |
-
["value", "display", "value", "Lore", "value"],
|
| 375 |
-
["value", "display", "value", "Lore"],
|
| 376 |
-
["value", "display", "value"],
|
| 377 |
];
|
| 378 |
|
| 379 |
for (const path of candidates) {
|
|
@@ -385,24 +317,19 @@ function createBot() {
|
|
| 385 |
}
|
| 386 |
if (!ok) continue;
|
| 387 |
|
| 388 |
-
// cur bir array veya compound olabilir
|
| 389 |
if (Array.isArray(cur) && cur.length > 0) {
|
| 390 |
const tryIndices = [1, cur.length - 1, 0];
|
| 391 |
for (const idx of tryIndices) {
|
| 392 |
const item = cur[idx];
|
| 393 |
if (!item) continue;
|
| 394 |
-
// item bazen { value: "..." } veya compound
|
| 395 |
if (typeof item === "string") {
|
| 396 |
-
const
|
| 397 |
-
const parsed = tryParseLoreText(text);
|
| 398 |
if (parsed != null) return parsed;
|
| 399 |
}
|
| 400 |
if (item && typeof item.value === "string") {
|
| 401 |
-
const
|
| 402 |
-
const parsed = tryParseLoreText(text);
|
| 403 |
if (parsed != null) return parsed;
|
| 404 |
}
|
| 405 |
-
// item compound: toString veya JSON parse dene
|
| 406 |
try {
|
| 407 |
const s = item.toString();
|
| 408 |
const parsed = tryParseLoreText(s);
|
|
@@ -417,62 +344,73 @@ function createBot() {
|
|
| 417 |
if (parsed != null) return parsed;
|
| 418 |
}
|
| 419 |
}
|
| 420 |
-
} catch (e) {
|
| 421 |
-
// devam et
|
| 422 |
-
}
|
| 423 |
}
|
| 424 |
|
| 425 |
-
// 2)
|
| 426 |
try {
|
| 427 |
-
// components array içinde 'lore' veya 'custom_data' olabilir
|
| 428 |
if (Array.isArray(slot.components)) {
|
| 429 |
for (const c of slot.components) {
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
const
|
| 438 |
-
const parsed = tryParseLoreText(String(text || ""));
|
| 439 |
if (parsed != null) return parsed;
|
| 440 |
}
|
|
|
|
|
|
|
|
|
|
| 441 |
}
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
}
|
| 451 |
-
}
|
| 452 |
}
|
| 453 |
-
}
|
| 454 |
}
|
| 455 |
}
|
|
|
|
| 456 |
|
| 457 |
-
|
|
|
|
| 458 |
if (slot.componentMap && typeof slot.componentMap === "object") {
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 469 |
}
|
| 470 |
}
|
| 471 |
-
}
|
| 472 |
}
|
| 473 |
} catch (e) {}
|
| 474 |
|
| 475 |
-
//
|
| 476 |
try {
|
| 477 |
const full = util.inspect(slot, { depth: null, maxArrayLength: null });
|
| 478 |
const parsed = tryParseLoreText(full);
|
|
@@ -490,7 +428,8 @@ function createBot() {
|
|
| 490 |
function tryParseLoreText(text) {
|
| 491 |
try {
|
| 492 |
if (!text || typeof text !== "string") return null;
|
| 493 |
-
|
|
|
|
| 494 |
let plain = text;
|
| 495 |
try {
|
| 496 |
const maybe = JSON.parse(text);
|
|
@@ -764,14 +703,12 @@ function createBot() {
|
|
| 764 |
} catch (e) {}
|
| 765 |
});
|
| 766 |
|
| 767 |
-
// Güvenli windowOpen handler: başlık, slot ve lore debug logları ekli
|
| 768 |
bot.on("windowOpen", function (window) {
|
| 769 |
try {
|
| 770 |
-
// window.title bazen ChatMessage veya obje olabilir; güvenli string'e çevir
|
| 771 |
let titleStr = parseWindowTitleToString(window.title);
|
| 772 |
-
logger.info(`[${config["bot-account"]["username"]}] windowOpen başlığı
|
| 773 |
|
| 774 |
-
// Esnek panel eşlemesi (küçük harfe çevirerek "besleyici" kelimesini arar)
|
| 775 |
const panelMatch = (titleStr && (titleStr.toLowerCase().includes("besleyici") || titleStr.includes("ʙᴇsʟᴇʏiᴄi")));
|
| 776 |
if (!panelMatch) {
|
| 777 |
try { bot.closeWindow(window); } catch (e) {}
|
|
@@ -785,21 +722,12 @@ function createBot() {
|
|
| 785 |
}
|
| 786 |
|
| 787 |
const beefSlots = window.slots.filter(xx => xx?.name && xx?.name === "cooked_beef");
|
| 788 |
-
logger.info(`[${config["bot-account"]["username"]}] windowOpen: beefSlots
|
| 789 |
|
| 790 |
if (beefSlots.length > 0) {
|
| 791 |
const beefSlot = beefSlots[0];
|
| 792 |
|
| 793 |
-
//
|
| 794 |
-
try {
|
| 795 |
-
const beefInfo = inspectBeefSlot(beefSlot);
|
| 796 |
-
logger.info(`[${config["bot-account"]["username"]}] beefSlot.inspect:\n${beefInfo.inspected}`);
|
| 797 |
-
logger.info(`[${config["bot-account"]["username"]}] beefSlot.nbtSummary:\n${beefInfo.nbtSummary}`);
|
| 798 |
-
} catch (e) {
|
| 799 |
-
logger.info(`[${config["bot-account"]["username"]}] beefSlot inspect alınamadı.`);
|
| 800 |
-
}
|
| 801 |
-
|
| 802 |
-
// Güvenli ekstraksiyon
|
| 803 |
const minyoncani = extractMinyonCanFromSlot(beefSlot);
|
| 804 |
|
| 805 |
if (minyoncani == null) {
|
|
@@ -818,7 +746,6 @@ function createBot() {
|
|
| 818 |
try { bot.closeWindow(window); } catch (e) {}
|
| 819 |
}
|
| 820 |
|
| 821 |
-
// Panel işlendi: bekleyen resolver'ları çağır
|
| 822 |
try {
|
| 823 |
while (windowOpenResolvers.length > 0) {
|
| 824 |
const r = windowOpenResolvers.shift();
|
|
|
|
| 165 |
return results;
|
| 166 |
}
|
| 167 |
|
| 168 |
+
// window.title parse yardımcı
|
| 169 |
function parseWindowTitleToString(titleObj) {
|
| 170 |
try {
|
| 171 |
if (!titleObj) return "";
|
|
|
|
| 199 |
}
|
| 200 |
}
|
| 201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
// --- Güvenli activate (öncelikle activateEntityAt kullanır, retry ve lookAt içerir) ---
|
| 203 |
async function safeActivateEntityPreferAt(entity, options = {}) {
|
| 204 |
const maxRetries = options.maxRetries ?? 3;
|
|
|
|
| 294 |
});
|
| 295 |
}
|
| 296 |
|
| 297 |
+
// --- Geliştirilmiş minyon canı çıkarma yardımcı fonksiyonu (custom_data.display.Lore string JSON formatını destekler) ---
|
| 298 |
function extractMinyonCanFromSlot(slot) {
|
| 299 |
try {
|
| 300 |
if (!slot) return null;
|
| 301 |
|
| 302 |
// 1) Eğer slot.nbt varsa önce oradan dene (çeşitli yollar)
|
| 303 |
if (slot.nbt) {
|
|
|
|
| 304 |
try {
|
|
|
|
| 305 |
const candidates = [
|
| 306 |
+
["value", "display", "value", "Lore", "value"],
|
| 307 |
+
["value", "display", "value", "Lore"],
|
| 308 |
+
["value", "display", "value"],
|
| 309 |
];
|
| 310 |
|
| 311 |
for (const path of candidates) {
|
|
|
|
| 317 |
}
|
| 318 |
if (!ok) continue;
|
| 319 |
|
|
|
|
| 320 |
if (Array.isArray(cur) && cur.length > 0) {
|
| 321 |
const tryIndices = [1, cur.length - 1, 0];
|
| 322 |
for (const idx of tryIndices) {
|
| 323 |
const item = cur[idx];
|
| 324 |
if (!item) continue;
|
|
|
|
| 325 |
if (typeof item === "string") {
|
| 326 |
+
const parsed = tryParseLoreText(item);
|
|
|
|
| 327 |
if (parsed != null) return parsed;
|
| 328 |
}
|
| 329 |
if (item && typeof item.value === "string") {
|
| 330 |
+
const parsed = tryParseLoreText(item.value);
|
|
|
|
| 331 |
if (parsed != null) return parsed;
|
| 332 |
}
|
|
|
|
| 333 |
try {
|
| 334 |
const s = item.toString();
|
| 335 |
const parsed = tryParseLoreText(s);
|
|
|
|
| 344 |
if (parsed != null) return parsed;
|
| 345 |
}
|
| 346 |
}
|
| 347 |
+
} catch (e) {}
|
|
|
|
|
|
|
| 348 |
}
|
| 349 |
|
| 350 |
+
// 2) components içinde custom_data veya lore varsa kontrol et (senin inspect çıktına göre burada display.Lore string JSON var)
|
| 351 |
try {
|
|
|
|
| 352 |
if (Array.isArray(slot.components)) {
|
| 353 |
for (const c of slot.components) {
|
| 354 |
+
if (!c) continue;
|
| 355 |
+
// custom_data -> data.value.display.value.Lore.value (string array)
|
| 356 |
+
if (c.type === "custom_data" && c.data && c.data.value && c.data.value.display && c.data.value.display.value && c.data.value.display.value.Lore) {
|
| 357 |
+
const loreObj = c.data.value.display.value.Lore;
|
| 358 |
+
// loreObj.value genelde array of strings
|
| 359 |
+
if (loreObj && loreObj.value && Array.isArray(loreObj.value)) {
|
| 360 |
+
for (const s of loreObj.value) {
|
| 361 |
+
const parsed = tryParseLoreText(String(s));
|
|
|
|
| 362 |
if (parsed != null) return parsed;
|
| 363 |
}
|
| 364 |
+
} else if (typeof loreObj === "string") {
|
| 365 |
+
const parsed = tryParseLoreText(loreObj);
|
| 366 |
+
if (parsed != null) return parsed;
|
| 367 |
}
|
| 368 |
+
}
|
| 369 |
+
|
| 370 |
+
// 'lore' component tipi varsa
|
| 371 |
+
if (c.type === "lore" && Array.isArray(c.data)) {
|
| 372 |
+
for (const entry of c.data) {
|
| 373 |
+
const text = safeGet(entry, ["value", "text", "value"]) || safeGet(entry, ["value", "extra", "value", 0, "value", "text", "value"]) || (entry && entry.toString && entry.toString());
|
| 374 |
+
const parsed = tryParseLoreText(String(text || ""));
|
| 375 |
+
if (parsed != null) return parsed;
|
|
|
|
|
|
|
| 376 |
}
|
| 377 |
+
}
|
| 378 |
}
|
| 379 |
}
|
| 380 |
+
} catch (e) {}
|
| 381 |
|
| 382 |
+
// 3) componentMap içinde 'custom_data' veya 'lore' anahtarlarını kontrol et
|
| 383 |
+
try {
|
| 384 |
if (slot.componentMap && typeof slot.componentMap === "object") {
|
| 385 |
+
// Map olabilir
|
| 386 |
+
const getFromMap = (m, key) => {
|
| 387 |
+
try {
|
| 388 |
+
if (m.get) return m.get(key);
|
| 389 |
+
return m[key];
|
| 390 |
+
} catch (e) { return null; }
|
| 391 |
+
};
|
| 392 |
+
|
| 393 |
+
const loreComp = getFromMap(slot.componentMap, "custom_data") || getFromMap(slot.componentMap, "lore");
|
| 394 |
+
if (loreComp) {
|
| 395 |
+
const data = loreComp.data || loreComp;
|
| 396 |
+
if (Array.isArray(data)) {
|
| 397 |
+
for (const entry of data) {
|
| 398 |
+
const text = safeGet(entry, ["value", "text", "value"]) || entry.toString?.();
|
| 399 |
+
const parsed = tryParseLoreText(String(text || ""));
|
| 400 |
+
if (parsed != null) return parsed;
|
| 401 |
+
}
|
| 402 |
+
} else if (data && data.value && Array.isArray(data.value)) {
|
| 403 |
+
for (const item of data.value) {
|
| 404 |
+
const text = safeGet(item, ["value", "text", "value"]) || item.toString?.();
|
| 405 |
+
const parsed = tryParseLoreText(String(text || ""));
|
| 406 |
+
if (parsed != null) return parsed;
|
| 407 |
}
|
| 408 |
}
|
| 409 |
+
}
|
| 410 |
}
|
| 411 |
} catch (e) {}
|
| 412 |
|
| 413 |
+
// 4) Fallback: tüm slot inspect'ini regex ile tara
|
| 414 |
try {
|
| 415 |
const full = util.inspect(slot, { depth: null, maxArrayLength: null });
|
| 416 |
const parsed = tryParseLoreText(full);
|
|
|
|
| 428 |
function tryParseLoreText(text) {
|
| 429 |
try {
|
| 430 |
if (!text || typeof text !== "string") return null;
|
| 431 |
+
|
| 432 |
+
// Eğer text JSON string ise parse etmeye çalış
|
| 433 |
let plain = text;
|
| 434 |
try {
|
| 435 |
const maybe = JSON.parse(text);
|
|
|
|
| 703 |
} catch (e) {}
|
| 704 |
});
|
| 705 |
|
| 706 |
+
// Güvenli windowOpen handler: başlık, slot ve lore debug logları ekli (log minimal)
|
| 707 |
bot.on("windowOpen", function (window) {
|
| 708 |
try {
|
|
|
|
| 709 |
let titleStr = parseWindowTitleToString(window.title);
|
| 710 |
+
logger.info(`[${config["bot-account"]["username"]}] windowOpen başlığı: ${titleStr}`);
|
| 711 |
|
|
|
|
| 712 |
const panelMatch = (titleStr && (titleStr.toLowerCase().includes("besleyici") || titleStr.includes("ʙᴇsʟᴇʏiᴄi")));
|
| 713 |
if (!panelMatch) {
|
| 714 |
try { bot.closeWindow(window); } catch (e) {}
|
|
|
|
| 722 |
}
|
| 723 |
|
| 724 |
const beefSlots = window.slots.filter(xx => xx?.name && xx?.name === "cooked_beef");
|
| 725 |
+
logger.info(`[${config["bot-account"]["username"]}] windowOpen: beefSlots=${beefSlots.length}`);
|
| 726 |
|
| 727 |
if (beefSlots.length > 0) {
|
| 728 |
const beefSlot = beefSlots[0];
|
| 729 |
|
| 730 |
+
// Minyon canını güvenli şekilde çıkar
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 731 |
const minyoncani = extractMinyonCanFromSlot(beefSlot);
|
| 732 |
|
| 733 |
if (minyoncani == null) {
|
|
|
|
| 746 |
try { bot.closeWindow(window); } catch (e) {}
|
| 747 |
}
|
| 748 |
|
|
|
|
| 749 |
try {
|
| 750 |
while (windowOpenResolvers.length > 0) {
|
| 751 |
const r = windowOpenResolvers.shift();
|