'use strict'; const dangerMobs = ['zombie','skeleton','creeper','spider','enderman','witch','phantom','drowned','husk','stray','blaze','piglin','zombified piglin','spider jockey']; const { ACTIONS } = require('./bot-model'); const Vec3 = require('vec3'); const DIR_VEC = [[0,0], [0,-1], [1,-1], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1]]; const rand = (a, b) => Math.floor(Math.random() * (b - a + 1)) + a; const sleep = ms => new Promise(r => setTimeout(r, ms)); class BotBrain { constructor(bot, manager, memory, miner, movement, world, shaper, model) { this.bot = bot; this.manager = manager; this.memory = memory; this.miner = miner; this.movement = movement; this.world = world; this.shaper = shaper || null; this.model = model || null; this._timer = null; this._fleeing = false; this._cmdCD = new Map(); this._state = 'IDLE'; this._idleUntil = 0; this._taskQueue = []; this._surroundings = { ores: [], crops: [], mobs: [], items: [] }; this._lastScanPos = null; this._scanTick = 0; this._craftTick = 0; this._lastDamage = Date.now(); this._lastChatTime = Date.now(); this._homePos = null; this._actionCooldowns = {}; this._actionResults = {}; // Server Optimizer mode (يعدل من bot-team.js) this._serverMode = 'normal'; this._tickInterval = 5000; // تسجيل الضرر bot.on('health', () => { if (bot.health < (this._lastHealth || 20)) this._lastDamage = Date.now(); this._lastHealth = bot.health; }); } start() { const loop = () => { if (!this._timer) return; this._tick(); this._timer = setTimeout(loop, Math.max(2000, this._tickInterval + rand(-1000, 1000))); }; this._timer = setTimeout(loop, Math.max(2000, this._tickInterval + rand(-1000, 1000))); } stop() { if (this._timer) { clearTimeout(this._timer); this._timer = null; } this.movement.stop(); } _tick() { if (!this.bot.entity || this.bot.health <= 0) return; // IDLE: 30% فرصة if (Date.now() < this._idleUntil) return; if (this._state !== 'IDLE' && Math.random() < 0.15) { this._setState('IDLE'); this._idleUntil = Date.now() + rand(8000, 25000); return; } // DANGER if (this._inDanger()) { if (this._hasWeapon() && this.bot.health > 10 && Math.random() > 0.2) { this._setState('FIGHT'); this._fightNearest(); } else { this._setState('FLEE'); this._flee(); } return; } // VOID/LAVA if (this.bot.entity.position.y < 0 || this._isOnLava()) { this._jumpOut(); return; } // SCAN this._scanTick++; if (this._scanTick % 4 === 0 && Math.random() < 0.5) this._scanSurroundings(); // GREET for (const name of Object.keys(this.bot.players)) { const pl = this.bot.players[name]; if (!pl || !pl.entity || name === this.bot.username) continue; if (this.bot.entity.position.distanceTo(pl.entity.position) > 10) continue; this.memory.see(name); if (this.memory.canGreet(name) && Math.random() < 0.6) { this.memory.markGreeted(name); this.memory.rememberInteraction(name, 'greeted'); const msgs = ['مرحبا ' + name, 'هلا ' + name, 'شلونك ' + name, 'ها ' + name]; this.bot.chat(msgs[rand(0, msgs.length - 1)]); } } // AUTO-CRAFT this._craftTick++; if (this._craftTick % 10 === 0 && Math.random() < 0.3) this._autoCraft(); // STATE MACHINE this._execState(); } _setState(s) { if (this._state === s) return; this._state = s; } _execState() { switch (this._state) { case 'FOLLOW': case 'FLEE': case 'FIGHT': case 'MINE': case 'FARM': case 'COLLECT': case 'CRAFT': break; case 'JUMP': case 'SNEAK': case 'SWIM': break; default: this._autoDecide(); break; } } async _autoDecide() { // AI Model — المتحكم الوحيد if (this.model && this.model.loaded && this.model.context.length >= 5) { const state = this.model.extractState(this.bot); if (state) { try { const result = await this.model.predict(state); const actionIdx = typeof result === 'object' ? result.actionIdx : result; const dirIdx = typeof result === 'object' ? result.dirIdx : 0; const actionName = ACTIONS[actionIdx]; if (this._execModelAction(actionName, dirIdx)) { this._actionResults[actionName] = (this._actionResults[actionName] || 0) + 1; return; } this._actionResults.__rejected = (this._actionResults.__rejected || 0) + 1; } catch (_) {} } } // إذا النموذج مش جاهز: wander بسيط مؤقت this._wander(rand(0, 3)); } setServerMode(mode) { this._serverMode = mode || 'normal'; switch (this._serverMode) { case 'critical': this._tickInterval = 8000; break; case 'moderate': this._tickInterval = 5000; break; default: this._tickInterval = 3000; break; } } _execModelAction(action, dirIdx) { // Action cooldowns — منع تكرار نفس الحركة بسرعة const now = Date.now(); const cd = this._actionCooldowns[action] || 0; if (now < cd) return false; this._actionCooldowns[action] = now + 2000; const s = this._surroundings; switch (action) { // ─── Original 10 ─── case 'COLLECT': if (s.items.length > 0) { this._setState('COLLECT'); this._collectItems(); return true; } break; case 'FIGHT': if (s.mobs.length > 0 && this._hasWeapon()) { this._setState('FIGHT'); this._fightNearest(); return true; } break; case 'MINE': if (s.ores.length > 0) { this._setState('MINE'); this._goMine(); return true; } break; case 'FARM': if (s.crops.length > 0) { this._setState('FARM'); this._goFarm(); return true; } break; case 'EXPLORE': this._explore(dirIdx); return true; case 'FLEE': this._setState('FLEE'); this._flee(dirIdx); return true; case 'CRAFT': this._autoCraft(); return true; case 'CHAT': this._chatRandom(); return true; case 'FOLLOW': this._follow(); return true; case 'IDLE': this._setState('IDLE'); this._idleUntil = Date.now() + rand(8000, 25000); return true; // ─── New 15 ─── case 'PLACE_BLOCK': this._placeBlock(); return true; case 'BUILD_SHELTER': this._buildShelter(); return true; case 'LIGHT_AREA': this._lightArea(); return true; case 'EAT': this._eat(); return true; case 'SLEEP': this._sleep(); return true; case 'GO_HOME': this._goHome(); return true; case 'EQUIP_ARMOR': this._equipArmor(); return true; case 'SMELT': this._setState('IDLE'); return true; // stub case 'JUMP': this._doJump(dirIdx); return true; case 'SPRINT': this._sprint(dirIdx); return true; case 'SNEAK': this._doSneak(); return true; case 'SWIM': this._doSwim(); return true; case 'EMOTE': this._doEmote(); return true; case 'WANDER': this._wander(dirIdx); return true; case 'HELP_ALLY': this._helpAlly(); return true; case 'TRADE': this._trade(); return true; case 'LOOK_AROUND': this._lookAround(); return true; // ─── 31 New Actions (Building, Mining, Crafting, Nether, End, Farm, Interact, Chat) ─── case 'BUILD_PATH': this._buildPath(dirIdx); return true; case 'BUILD_BRIDGE': this._buildBridge(dirIdx); return true; case 'BUILD_WALL': this._buildWall(); return true; case 'PLACE_DOOR': this._placeDoor(); return true; case 'PLACE_LADDER': this._placeLadder(dirIdx); return true; case 'MINE_IRON': this._mineIron(); return true; case 'MINE_GOLD': this._mineGold(); return true; case 'MINE_DIAMOND': this._mineDiamond(); return true; case 'MINE_OBSIDIAN': this._mineObsidian(); return true; case 'CRAFT_ENCHANT_TABLE': this._craftEnchantTable(); return true; case 'CRAFT_ANVIL': this._craftAnvil(); return true; case 'CRAFT_BREWING_STAND': this._craftBrewingStand(); return true; case 'CRAFT_BED': this._craftBed(); return true; case 'CRAFT_BOAT': this._craftBoat(); return true; case 'ENTER_NETHER': this._enterNether(); return true; case 'EXPLORE_NETHER': this._exploreNether(dirIdx); return true; case 'FIGHT_BLAZE': this._fightBlaze(); return true; case 'ENTER_END': this._enterEnd(); return true; case 'FIGHT_DRAGON': this._fightDragon(); return true; case 'PLANT_CROP': this._plantCrop(); return true; case 'HARVEST_CROP': this._harvestCrop(); return true; case 'FISH': this._fish(); return true; case 'SHEAR': this._shear(); return true; case 'MILK': this._milk(); return true; case 'SLEEP_AT_VILLAGE': this._sleepAtVillage(); return true; case 'CHAT_GREETING': this._chatGreeting(); return true; case 'CHAT_STATUS': this._chatStatus(); return true; case 'CHAT_THANK': this._chatThank(); return true; case 'CHAT_QUESTION': this._chatQuestion(); return true; case 'CHAT_ALERT': this._chatAlert(); return true; case 'THINK': this._thinkDeep(); return true; } this._explore(); return true; } // ════════════════════════════════════════ // المسح والتصنيع // ════════════════════════════════════════ _scanSurroundings() { const pos = this.bot.entity.position; this._surroundings = { ores: [], crops: [], mobs: [], items: [] }; const scanRange = 4; for (let dx = -scanRange; dx <= scanRange; dx++) { for (let dz = -scanRange; dz <= scanRange; dz++) { for (let dy = -2; dy <= 2; dy++) { const bp = pos.offset(dx, dy, dz); const b = this.bot.blockAt(bp); if (!b || b.name === 'air') continue; if (b.name.includes('_ore')) { this._surroundings.ores.push({ block: b, pos: bp, dist: Math.abs(dx) + Math.abs(dy) + Math.abs(dz) }); this.world.addOreSpot(Math.floor(bp.x), Math.floor(bp.y), Math.floor(bp.z), b.name); } if (['wheat','carrots','potatoes','beetroots'].includes(b.name) && b.metadata >= 7) { this._surroundings.crops.push({ block: b, pos: bp, dist: Math.abs(dx) + Math.abs(dz) }); } } } } this._surroundings.ores.sort((a, b) => a.dist - b.dist); this._surroundings.crops.sort((a, b) => a.dist - b.dist); for (const e of Object.values(this.bot.entities)) { if (!e || e === this.bot.entity) continue; const d = pos.distanceTo(e.position); if (d > 10) continue; if (e.type === 'mob' && dangerMobs.includes((e.name || e.displayName || '').toLowerCase())) { this._surroundings.mobs.push({ entity: e, dist: d }); } if (e.type === 'object') this._surroundings.items.push({ entity: e, dist: d }); } this._surroundings.mobs.sort((a, b) => a.dist - b.dist); this._surroundings.items.sort((a, b) => a.dist - b.dist); } _autoCraft() { if (this._state === 'CRAFT' || this.movement.isMoving()) return; const tools = this.bot.inventory.items().filter(i => i.name.includes('pickaxe') || i.name.includes('axe') || i.name.includes('sword')); const planks = this.bot.inventory.count('oak_planks') + this.bot.inventory.count('spruce_planks') + this.bot.inventory.count('birch_planks'); const logs = this.bot.inventory.count('oak_log') + this.bot.inventory.count('spruce_log') + this.bot.inventory.count('birch_log'); if (tools.length === 0 && (planks >= 3 || logs >= 1)) { this._setState('CRAFT'); this.miner.craftItem('wooden_pickaxe').then(r => this._setState('IDLE')); } else if (tools.length <= 1 && planks < 3 && logs >= 1) { this._setState('CRAFT'); this.miner.craftItem('planks').then(r => this._setState('IDLE')); } } // ════════════════════════════════════════ // EXECUTION METHODS // ════════════════════════════════════════ _goMine() { const ore = this._surroundings.ores[0]; if (!ore) { this._setState('IDLE'); return; } this.movement.goto(ore.pos.x, ore.pos.z).then(ok => { if (!ok) { this._setState('IDLE'); return; } this.miner.mineOre(ore.block).then(r => { if (r) this.world.markOreMined(Math.floor(ore.pos.x), Math.floor(ore.pos.y), Math.floor(ore.pos.z)); this._setState('IDLE'); }); }); } _goFarm() { const crop = this._surroundings.crops[0]; if (!crop) { this._setState('IDLE'); return; } this.movement.goto(crop.pos.x, crop.pos.z).then(ok => { if (!ok) { this._setState('IDLE'); return; } this.miner.harvestCrop(crop.block).then(r => this._setState('IDLE')); }); } _collectItems() { const item = this._surroundings.items[0]; if (!item) { this._setState('IDLE'); return; } const p = item.entity.position; this.movement.goto(p.x, p.z).then(ok => this._setState('IDLE')); } _fightNearest() { const mob = this._surroundings.mobs[0]; if (!mob) { this._setState('IDLE'); return; } this._fightEntity(mob.entity); } _fightEntity(entity) { if (!entity || entity.isDead || !this.bot.entity) { this._setState('IDLE'); return; } const d = this.bot.entity.position.distanceTo(entity.position); if (d > 10) { this._setState('IDLE'); return; } if (this.shaper && this.shaper.lookAt) { this.shaper.lookAt(entity.position.offset( (Math.random() - 0.5) * 0.3, 1 + (Math.random() - 0.5) * 0.3, (Math.random() - 0.5) * 0.3 )); } else { this.bot.lookAt(entity.position.offset( (Math.random() - 0.5) * 0.3, 1 + (Math.random() - 0.5) * 0.3, (Math.random() - 0.5) * 0.3 ), false); } setTimeout(() => { if (!entity || entity.isDead || !this.bot.entity) { this._setState('IDLE'); return; } this.bot.attack(entity); setTimeout(() => this._fightEntity(entity), rand(800, 1400)); }, rand(300, 700)); } _explore(dirIdx) { this._setState('EXPLORE'); if (!this.movement.isMoving()) { const r = this.bot.entity.position; const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; if (dx === 0 && dz === 0) { this.movement.goto(r.x + rand(-15, 15), r.z + rand(-15, 15)); } else { this.movement.goto(r.x + dx * 15, r.z + dz * 15); } } } _wander(dirIdx) { this._setState('WANDER'); if (!this.movement.isMoving()) { const r = this.bot.entity.position; const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; if (dx === 0 && dz === 0) { this.movement.goto(r.x + rand(-30, 30), r.z + rand(-30, 30)); } else { this.movement.goto(r.x + dx * 30, r.z + dz * 30); } } } _chatRandom() { const msgs = [ 'السلام عليكم', 'كيف اللعب؟', 'وش تسوي؟', 'تعال هنا', 'شكلك محترف', 'الماين كرفت مرة حلو', 'تعاون؟', 'هههه', 'تم', 'ايوا', 'لا', 'ماشي', ]; this.bot.chat(msgs[rand(0, msgs.length - 1)]); this._setState('IDLE'); } _follow() { const target = Object.keys(this.bot.players).find(n => n !== this.bot.username); if (!target) { this._setState('IDLE'); return; } this._setState('FOLLOW'); const loop = () => { if (this._state !== 'FOLLOW') return; const p = this.bot.players[target]; if (!p || !p.entity) { this._setState('IDLE'); return; } const d = this.bot.entity.position.distanceTo(p.entity.position); if (d > 3) { this.movement.goto(p.entity.position.x, p.entity.position.z); } setTimeout(loop, 3000); }; loop(); } // ════════════════════════════════════════ // بناء // ════════════════════════════════════════ _placeBlock() { const blocks = ['oak_planks','cobblestone','dirt','stone']; const item = this._findItem(blocks); if (!item) { this._setState('IDLE'); return; } this._setState('PLACE_BLOCK'); this.bot.equip(item, 'hand').then(() => { const pos = this.bot.entity.position; const target = this.bot.blockAt(pos.offset(0, -1, 0)); if (!target) { this._setState('IDLE'); return; } this.bot.placeBlock(target, new Vec3(0, 1, 0)).catch(() => {}); setTimeout(() => this._setState('IDLE'), 1000); }); } _buildShelter() { const blocks = ['oak_planks','cobblestone','dirt']; const item = this._findItem(blocks); if (!item) { this._setState('IDLE'); return; } this._setState('BUILD_SHELTER'); const pos = this.bot.entity.position; const startX = Math.floor(pos.x); const startZ = Math.floor(pos.z); this.bot.equip(item, 'hand').then(async () => { // أرضية 5×5 for (let x = 0; x < 5; x++) { for (let z = 0; z < 5; z++) { const b = this.bot.blockAt(pos.offset(x - 2, -1, z - 2)); if (b && (b.name === 'air' || b.name.includes('grass') || b.name.includes('dirt'))) { try { await this.bot.placeBlock(b, new Vec3(0, 1, 0)); } catch (_) {} await sleep(rand(200, 500)); } } } // جدران 3 عالية for (let h = 1; h <= 3; h++) { for (let x = 0; x < 5; x++) { for (let z = 0; z < 5; z++) { if ((x > 0 && x < 4 && z > 0 && z < 4)) continue; // داخل if (x === 2 && z === 4 && h === 1) continue; // باب const target = this.bot.blockAt(pos.offset(x - 2, h - 1, z - 2)); if (target && target.name !== 'air') continue; const refBlock = this.bot.blockAt(pos.offset(x - 2, h - 2, z - 2)); if (!refBlock) continue; try { await this.bot.placeBlock(refBlock, new Vec3(0, 1, 0)); } catch (_) {} await sleep(rand(200, 400)); } } } this._setState('IDLE'); }); } _lightArea() { const torch = this._findItem(['torch']); if (!torch) { this._setState('IDLE'); return; } this._setState('LIGHT_AREA'); this.bot.equip(torch, 'hand').then(async () => { const pos = this.bot.entity.position; for (let dx = -2; dx <= 2; dx += 2) { for (let dz = -2; dz <= 2; dz += 2) { const target = this.bot.blockAt(pos.offset(dx, 0, dz)); if (!target || target.name !== 'air') continue; const ref = this.bot.blockAt(pos.offset(dx, -1, dz)); if (!ref || ref.name === 'air') continue; try { await this.bot.placeBlock(ref, new Vec3(0, 1, 0)); await sleep(rand(200, 400)); } catch (_) {} } } this._setState('IDLE'); }); } // ════════════════════════════════════════ // بقاء // ════════════════════════════════════════ _eat() { const foodNames = ['apple','bread','cooked_beef','cooked_porkchop','cooked_chicken', 'baked_potato','carrot','golden_carrot','beetroot','melon_slice', 'cooked_mutton','cooked_cod','cooked_salmon','steak','porkchop', 'mushroom_stew','suspicious_stew']; const food = this._findItem(foodNames); if (!food) { this._setState('IDLE'); return; } this._setState('EAT'); this.bot.equip(food, 'hand').then(() => { this.bot.consume().catch(() => {}); setTimeout(() => this._setState('IDLE'), 2000); }); } _sleep() { // ابحث عن سرير قريب const pos = this.bot.entity.position; for (let dx = -4; dx <= 4; dx++) { for (let dz = -4; dz <= 4; dz++) { for (let dy = -1; dy <= 1; dy++) { const b = this.bot.blockAt(pos.offset(dx, dy, dz)); if (b && (b.name.includes('bed'))) { this._setState('SLEEP'); this.movement.goto(b.position.x, b.position.z).then(() => { this.bot.sleep(b).catch(() => {}); setTimeout(() => { this.bot.wake().catch(() => {}); this._setState('IDLE'); }, rand(5000, 15000)); }); return; } } } } this._setState('IDLE'); } _goHome() { const home = this._homePos || { x: 0, y: 64, z: 0 }; this._setState('GO_HOME'); this.movement.goto(home.x, home.z).then(() => this._setState('IDLE')); } _equipArmor() { const inv = this.bot.inventory.items(); const armor = [ { slot: 'torso', names: ['chestplate','elytra'] }, { slot: 'feet', names: ['boots'] }, { slot: 'head', names: ['helmet','skull','head'] }, { slot: 'legs', names: ['leggings'] }, ]; for (const a of armor) { const item = inv.find(i => a.names.some(n => i.name.includes(n))); if (item) this.bot.equip(item, a.slot).catch(() => {}); } this._setState('IDLE'); } // ════════════════════════════════════════ // حركة (سلوك بشري) // ════════════════════════════════════════ _doSneak() { this.bot.setControlState('sneak', true); this._setState('SNEAK'); setTimeout(() => { this.bot.setControlState('sneak', false); this._setState('IDLE'); }, rand(2000, 5000)); } _doSwim() { if (!this.bot.entity.isInWater) { this._setState('IDLE'); return; } this.bot.setControlState('forward', true); this.bot.setControlState('jump', true); this._setState('SWIM'); setTimeout(() => { this.bot.setControlState('forward', false); this.bot.setControlState('jump', false); this._setState('IDLE'); }, rand(2000, 4000)); } _doEmote() { const emotes = ['*يتثاوب*','*يلوح*','*يرقص*','*ينظر حوله*','*يجلس*','*يفكر*']; this.bot.chat(emotes[rand(0, emotes.length - 1)]); setTimeout(() => { this.bot.animation(0, 1); this._setState('IDLE'); }, 500); } // ─── التوابع المساعدة للـ 31 action ─── _findNearestBlock(names) { const pos = this.bot.entity.position; let nearest = null, minDist = Infinity; for (let x = -20; x <= 20; x++) { for (let z = -20; z <= 20; z++) { for (let y = -5; y <= 5; y++) { const b = this.bot.blockAt(pos.offset(x, y, z)); if (b && names.some(n => b.name.includes(n))) { const d = pos.distanceTo(b.position); if (d < minDist) { minDist = d; nearest = b; } } } } } return nearest; } _findNearestEntity(name) { for (const e of Object.values(this.bot.entities)) { if (!e || e === this.bot.entity) continue; if ((e.name || '').includes(name)) return e; } return null; } _attackEntity(entity) { this.bot.lookAt(entity.position.offset(0, 1, 0), true).then(() => { this.bot.attack(entity); }); } async _placePathBlocks(target) { const blocks = ['cobblestone', 'stone', 'oak_planks']; const item = this._findItem(blocks); if (!item) return; await this.bot.equip(item, 'hand'); const start = this.bot.entity.position.floored(); const dx = Math.sign(target.x - start.x); const dz = Math.sign(target.z - start.z); for (let i = 0; i < 10; i++) { const pos = start.offset(dx * i, -1, dz * i); const below = this.bot.blockAt(pos); if (below && below.name === 'air') { const ref = this.bot.blockAt(pos.offset(0, -1, 0)); if (ref) { try { await this.bot.placeBlock(ref, new Vec3(0, 1, 0)); } catch (_) {} await sleep(200); } } } } async _bridgeForward(start, dx, dz) { const blocks = ['cobblestone', 'dirt', 'oak_planks']; const item = this._findItem(blocks); if (!item) return; await this.bot.equip(item, 'hand'); for (let i = 1; i <= 5; i++) { const pos = start.offset(dx * i, -1, dz * i); const below = this.bot.blockAt(pos); if (below && below.name === 'air') { const ref = this.bot.blockAt(pos.offset(0, -1, 0)); if (ref) { try { await this.bot.placeBlock(ref, new Vec3(0, 1, 0)); } catch (_) {} await sleep(300); } } } } async _placeWallSegment() { const blocks = ['cobblestone', 'stone', 'oak_planks']; const item = this._findItem(blocks); if (!item) return; await this.bot.equip(item, 'hand'); const pos = this.bot.entity.position.floored(); for (let x = -2; x <= 2; x++) { for (let y = 0; y < 3; y++) { const target = this.bot.blockAt(pos.offset(x, y, 0)); if (target && target.name !== 'air') continue; const ref = this.bot.blockAt(pos.offset(x, y - 1, 0)); if (!ref) continue; try { await this.bot.placeBlock(ref, new Vec3(0, 1, 0)); } catch (_) {} await sleep(200); } } } // ─── 31 New Actions (full implementations) ─── _buildPath(dirIdx) { this._setState('BUILD_PATH'); const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; const target = this.bot.entity.position.offset(dx * 15, 0, dz * 15); this._placePathBlocks(target); setTimeout(() => this._setState('IDLE'), 2000); } _buildBridge(dirIdx) { this._setState('BUILD_BRIDGE'); const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; const start = this.bot.entity.position.floored(); this._bridgeForward(start, dx, dz); setTimeout(() => this._setState('IDLE'), 3000); } _buildWall() { this._setState('BUILD_WALL'); this._placeWallSegment(); setTimeout(() => this._setState('IDLE'), 3000); } _placeDoor() { this._setState('PLACE_DOOR'); const door = this._findItem(['door', 'trapdoor']); if (!door) { this._setState('IDLE'); return; } this.bot.equip(door, 'hand').then(() => { const pos = this.bot.entity.position.floored(); const target = this.bot.blockAt(pos.offset(0, -1, 0)); if (target) { this.bot.placeBlock(target, new Vec3(0, 1, 0)).catch(() => {}); } setTimeout(() => this._setState('IDLE'), 1000); }); } _placeLadder(dirIdx) { this._setState('PLACE_LADDER'); const ladder = this._findItem(['ladder']); if (!ladder) { this._setState('IDLE'); return; } this.bot.equip(ladder, 'hand').then(() => { const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; const pos = this.bot.entity.position.floored(); for (let y = 0; y < 4; y++) { const target = this.bot.blockAt(pos.offset(dx, y, dz)); if (!target || target.name !== 'air') continue; const ref = this.bot.blockAt(pos.offset(dx, y - 1, dz)); if (!ref) continue; this.bot.placeBlock(ref, new Vec3(-dx, 0, -dz)).catch(() => {}); } setTimeout(() => this._setState('IDLE'), 1000); }); } _mineIron() { this._setState('MINE_IRON'); this.miner.mineOre({ name: 'iron_ore' }).then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _mineGold() { this._setState('MINE_GOLD'); this.miner.mineOre({ name: 'gold_ore' }).then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _mineDiamond() { this._setState('MINE_DIAMOND'); this.miner.mineOre({ name: 'diamond_ore' }).then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _mineObsidian() { this._setState('MINE_OBSIDIAN'); const block = this._findNearestBlock(['obsidian']); if (block) { this.movement.goto(block.position.x, block.position.z).then(() => { this.bot.dig(block).catch(() => {}); }); } setTimeout(() => this._setState('IDLE'), 3000); } _craftEnchantTable() { this._setState('CRAFT'); this.miner.craftItem('enchanting_table').then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _craftAnvil() { this._setState('CRAFT'); this.miner.craftItem('anvil').then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _craftBrewingStand() { this._setState('CRAFT'); this.miner.craftItem('brewing_stand').then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _craftBed() { this._setState('CRAFT'); this.miner.craftItem('bed').then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _craftBoat() { this._setState('CRAFT'); this.miner.craftItem('boat').then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _enterNether() { this._setState('ENTER_NETHER'); const portal = this._findNearestBlock(['nether_portal', 'portal']); if (portal) { this.movement.goto(portal.position.x, portal.position.z).then(() => { this.bot.activateBlock(portal).catch(() => {}); }); } setTimeout(() => this._setState('IDLE'), 3000); } _exploreNether(dirIdx) { this._explore(dirIdx); } _fightBlaze() { this._setState('FIGHT'); const blaze = this._findNearestEntity('blaze'); if (blaze) this._attackEntity(blaze); setTimeout(() => this._setState('IDLE'), 2000); } _enterEnd() { this._setState('ENTER_END'); const portal = this._findNearestBlock(['end_portal', 'end_gateway']); if (portal) { this.movement.goto(portal.position.x, portal.position.z).then(() => { this.bot.activateBlock(portal).catch(() => {}); }); } setTimeout(() => this._setState('IDLE'), 3000); } _fightDragon() { this._setState('FIGHT'); const dragon = this._findNearestEntity('ender_dragon'); if (dragon) this._attackEntity(dragon); setTimeout(() => this._setState('IDLE'), 2000); } _plantCrop() { this._setState('FARM'); const seeds = this._findItem(['wheat_seeds', 'carrot', 'potato', 'beetroot_seeds']); if (!seeds) { this._setState('IDLE'); return; } this.bot.equip(seeds, 'hand').then(() => { const pos = this.bot.entity.position.floored(); for (let x = -2; x <= 2; x++) { for (let z = -2; z <= 2; z++) { const farmland = this.bot.blockAt(pos.offset(x, -1, z)); if (farmland && farmland.name === 'farmland') { const above = this.bot.blockAt(pos.offset(x, 0, z)); if (above && above.name === 'air') { this.bot.placeBlock(above, new Vec3(0, 1, 0)).catch(() => {}); } } } } setTimeout(() => this._setState('IDLE'), 2000); }); } _harvestCrop() { this._setState('FARM'); this.miner.harvestCrop().then(() => this._setState('IDLE')).catch(() => this._setState('IDLE')); } _fish() { this._setState('FISH'); const rod = this._findItem(['fishing_rod']); if (!rod) { this._setState('IDLE'); return; } this.bot.equip(rod, 'hand').then(() => { this.bot.fish(); setTimeout(() => { this.bot.activateItem().catch(() => {}); this._setState('IDLE'); }, 5000); }); } _shear() { this._setState('SHEAR'); const shears = this._findItem(['shears']); if (!shears) { this._setState('IDLE'); return; } const sheep = this._findNearestEntity('sheep'); if (!sheep) { this._setState('IDLE'); return; } this.bot.equip(shears, 'hand').then(() => { this.movement.goto(sheep.position.x, sheep.position.z).then(() => { this.bot.shear(sheep).catch(() => {}); this._setState('IDLE'); }); }); } _milk() { this._setState('MILK'); const bucket = this._findItem(['bucket']); if (!bucket) { this._setState('IDLE'); return; } const cow = this._findNearestEntity('cow'); if (!cow) { this._setState('IDLE'); return; } this.bot.equip(bucket, 'hand').then(() => { this.movement.goto(cow.position.x, cow.position.z).then(() => { this.bot.milk(cow).catch(() => {}); this._setState('IDLE'); }); }); } _sleepAtVillage() { this._sleep(); } _chatGreeting() { const msgs = ['السلام عليكم', 'مرحباً', 'هلا']; this.bot.chat(msgs[rand(0, msgs.length - 1)]); this._setState('IDLE'); } _chatStatus() { this.bot.chat('صحتي ' + Math.round(this.bot.health) + ' | طعامي ' + Math.round(this.bot.food)); this._setState('IDLE'); } _chatThank() { this.bot.chat('شكراً'); this._setState('IDLE'); } _chatQuestion() { const qs = ['كيف اللعب؟', 'وش تسوي؟', 'تعاون؟']; this.bot.chat(qs[rand(0, qs.length - 1)]); this._setState('IDLE'); } _chatAlert() { this.bot.chat('انتبه! خطر'); this._setState('IDLE'); } _thinkDeep() { this._setState('THINK'); setTimeout(() => this._setState('IDLE'), rand(3000, 8000)); } _helpAlly() { // ابحث عن البوت الآخر const other = Object.keys(this.bot.players).find(n => n !== this.bot.username && (n.includes('bot') || n.includes('Alex') || n.includes('Steve') || n.includes('Night') || n.includes('Redstone')) ); if (!other) { this._setState('IDLE'); return; } const p = this.bot.players[other]; if (!p || !p.entity) { this._setState('IDLE'); return; } this._setState('HELP_ALLY'); this.movement.goto(p.entity.position.x, p.entity.position.z).then(() => { this.bot.chat('جيت اساعدك ' + other); this._setState('IDLE'); }); } _trade() { // ابحث عن قروي const pos = this.bot.entity.position; for (const e of Object.values(this.bot.entities)) { if (!e || e === this.bot.entity) continue; const mobName = (e.name || e.displayName || '').toLowerCase(); if (mobName === 'villager') { if (pos.distanceTo(e.position) > 5) { this._setState('TRADE'); this.movement.goto(e.position.x, e.position.z); return; } // تبادل (أول trade) this.bot.trade(e, 0, 1).catch(() => {}); this._setState('IDLE'); return; } } this._setState('IDLE'); } _lookAround() { this._setState('LOOK_AROUND'); if (this.shaper && this.shaper.lookAt) { const pos = this.bot.entity.position; this.shaper.lookAt(pos.offset(rand(-5, 5), rand(0, 2), rand(-5, 5))); } setTimeout(() => { this._scanSurroundings(); this._setState('IDLE'); }, rand(1500, 3000)); } // ════════════════════════════════════════ // أدوات مساعدة // ════════════════════════════════════════ _findItem(names) { const items = this.bot.inventory.items(); for (const n of names) { const found = items.find(i => i.name.includes(n)); if (found) return found; } return null; } _inDanger() { for (const e of Object.values(this.bot.entities)) { if (!e || e === this.bot.entity || e.type !== 'mob') continue; if (dangerMobs.includes((e.name || e.displayName || '').toLowerCase())) { if (this.bot.entity.position.distanceTo(e.position) < 6) return true; } } return false; } _isOnLava() { const b = this.bot.blockAt(this.bot.entity.position.offset(0, -1, 0)); return b && (b.name.includes('lava') || b.name.includes('fire')); } _hasWeapon() { return this.bot.inventory.items().some(i => i.name.includes('sword') || i.name.includes('axe')); } _flee(dirIdx) { if (this._fleeing) return; this._fleeing = true; this.bot.setControlState('back', true); this.bot.setControlState('jump', true); setTimeout(() => { this.bot.setControlState('back', false); this.bot.setControlState('jump', false); this._fleeing = false; }, 1800); } _doJump(dirIdx) { this._setState('JUMP'); const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; if (dx !== 0 || dz !== 0) { this.bot.lookAt(this.bot.entity.position.offset(dx * 5, 0, dz * 5), true); } this.bot.setControlState('jump', true); this.bot.setControlState('forward', true); setTimeout(() => { this.bot.setControlState('jump', false); this.bot.setControlState('forward', false); this._setState('IDLE'); }, 1200); } _sprint(dirIdx) { this._setState('SPRINT'); const [dx, dz] = DIR_VEC[dirIdx || 0] || [0, 0]; if (dx !== 0 || dz !== 0) { this.bot.lookAt(this.bot.entity.position.offset(dx * 5, 0, dz * 5), true); } this.bot.setControlState('sprint', true); this.bot.setControlState('forward', true); setTimeout(() => { this.bot.setControlState('sprint', false); this.bot.setControlState('forward', false); this._setState('IDLE'); }, rand(2000, 4000)); } _jumpOut() { this.bot.setControlState('jump', true); this.bot.setControlState('forward', true); setTimeout(() => { this.bot.setControlState('jump', false); this.bot.setControlState('forward', false); }, 2500); } } module.exports = { BotBrain };